sortable_skima 0.2.0.25
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.
- checksums.yaml +7 -0
 - data/README.md +192 -0
 - data/app/assets/javascripts/jquery-ui.min.js +12 -0
 - data/app/assets/javascripts/jquery.ba-bbq.js +1137 -0
 - data/app/assets/javascripts/skima-sortable-tables_2_0_10.js +450 -0
 - data/app/assets/stylesheets/images/animated-overlay.gif +0 -0
 - data/app/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
 - data/app/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
 - data/app/assets/stylesheets/images/ui-icons_222222_256x240.png +0 -0
 - data/app/assets/stylesheets/images/ui-icons_2e83ff_256x240.png +0 -0
 - data/app/assets/stylesheets/images/ui-icons_454545_256x240.png +0 -0
 - data/app/assets/stylesheets/images/ui-icons_888888_256x240.png +0 -0
 - data/app/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png +0 -0
 - data/app/assets/stylesheets/jquery-ui.css +1183 -0
 - data/app/controllers/sortables_controller.rb +75 -0
 - data/app/models/sortable.rb +82 -0
 - data/config/routes.rb +5 -0
 - data/doc/Backtrace.html +493 -0
 - data/doc/README_rdoc.html +329 -0
 - data/doc/SortableHelper.html +364 -0
 - data/doc/SortableSkima.html +343 -0
 - data/doc/SortableSkima/Engine.html +131 -0
 - data/doc/created.rid +7 -0
 - data/doc/images/add.png +0 -0
 - data/doc/images/brick.png +0 -0
 - data/doc/images/brick_link.png +0 -0
 - data/doc/images/bug.png +0 -0
 - data/doc/images/bullet_black.png +0 -0
 - data/doc/images/bullet_toggle_minus.png +0 -0
 - data/doc/images/bullet_toggle_plus.png +0 -0
 - data/doc/images/date.png +0 -0
 - data/doc/images/delete.png +0 -0
 - data/doc/images/find.png +0 -0
 - data/doc/images/loadingAnimation.gif +0 -0
 - data/doc/images/macFFBgHack.png +0 -0
 - data/doc/images/package.png +0 -0
 - data/doc/images/page_green.png +0 -0
 - data/doc/images/page_white_text.png +0 -0
 - data/doc/images/page_white_width.png +0 -0
 - data/doc/images/plugin.png +0 -0
 - data/doc/images/ruby.png +0 -0
 - data/doc/images/tag_blue.png +0 -0
 - data/doc/images/tag_green.png +0 -0
 - data/doc/images/transparent.png +0 -0
 - data/doc/images/wrench.png +0 -0
 - data/doc/images/wrench_orange.png +0 -0
 - data/doc/images/zoom.png +0 -0
 - data/doc/index.html +347 -0
 - data/doc/js/darkfish.js +155 -0
 - data/doc/js/jquery.js +18 -0
 - data/doc/js/navigation.js +142 -0
 - data/doc/js/search.js +94 -0
 - data/doc/js/search_index.js +1 -0
 - data/doc/js/searcher.js +228 -0
 - data/doc/rdoc.css +543 -0
 - data/doc/sortable_parser.html +78 -0
 - data/doc/table_of_contents.html +114 -0
 - data/lib/sortable_skima.rb +122 -0
 - data/lib/sortable_skima/active_record.rb +36 -0
 - data/lib/sortable_skima/backtrace.rb +53 -0
 - data/lib/sortable_skima/engine.rb +63 -0
 - data/lib/sortable_skima/helpers/sortable_helper.rb +188 -0
 - metadata +142 -0
 
| 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <!DOCTYPE html>
         
     | 
| 
      
 2 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 3 
     | 
    
         
            +
            <head lang="en">
         
     | 
| 
      
 4 
     | 
    
         
            +
                <meta charset="UTF-8">
         
     | 
| 
      
 5 
     | 
    
         
            +
                <title>SortableConverter</title>
         
     | 
| 
      
 6 
     | 
    
         
            +
                <script src="js/jquery.js"></script>
         
     | 
| 
      
 7 
     | 
    
         
            +
            </head>
         
     | 
| 
      
 8 
     | 
    
         
            +
            <body>
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            <script type="application/javascript">
         
     | 
| 
      
 11 
     | 
    
         
            +
                $(function(){
         
     | 
| 
      
 12 
     | 
    
         
            +
                    $('#convertBtn').click(convertHtml);
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    function convertHtml(){
         
     | 
| 
      
 15 
     | 
    
         
            +
                        var input = $('#inputField').val();
         
     | 
| 
      
 16 
     | 
    
         
            +
                        var outPut = '';
         
     | 
| 
      
 17 
     | 
    
         
            +
                        var columns = [];
         
     | 
| 
      
 18 
     | 
    
         
            +
                        var widths = [];
         
     | 
| 
      
 19 
     | 
    
         
            +
                        var match;
         
     | 
| 
      
 20 
     | 
    
         
            +
                        var widthsRX = /<col\s*width=(["'])([^'"]+)/g
         
     | 
| 
      
 21 
     | 
    
         
            +
                        match = widthsRX.exec(input);
         
     | 
| 
      
 22 
     | 
    
         
            +
                        while (match != null) {
         
     | 
| 
      
 23 
     | 
    
         
            +
                            widths.push(match[2]);
         
     | 
| 
      
 24 
     | 
    
         
            +
                            match = widthsRX.exec(input);
         
     | 
| 
      
 25 
     | 
    
         
            +
                        }
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                        var titles = [];
         
     | 
| 
      
 29 
     | 
    
         
            +
                        var fields = [];
         
     | 
| 
      
 30 
     | 
    
         
            +
                        var fieldsRX = /<th.*(sortField.*["'](.*)["'])*.*>(.*)<\//g
         
     | 
| 
      
 31 
     | 
    
         
            +
                        var sortFieldRX = /sortField.*["'](.*)["']/
         
     | 
| 
      
 32 
     | 
    
         
            +
                        match = fieldsRX.exec(input);
         
     | 
| 
      
 33 
     | 
    
         
            +
                        while (match != null) {
         
     | 
| 
      
 34 
     | 
    
         
            +
                            if(match){
         
     | 
| 
      
 35 
     | 
    
         
            +
                                titles.push(match[3]);
         
     | 
| 
      
 36 
     | 
    
         
            +
                                var fieldMatch = sortFieldRX.exec(match[0]);
         
     | 
| 
      
 37 
     | 
    
         
            +
                                if(fieldMatch){
         
     | 
| 
      
 38 
     | 
    
         
            +
                                    fields.push(fieldMatch[1]);
         
     | 
| 
      
 39 
     | 
    
         
            +
                                }else{
         
     | 
| 
      
 40 
     | 
    
         
            +
                                    fields.push(null);
         
     | 
| 
      
 41 
     | 
    
         
            +
                                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                            }
         
     | 
| 
      
 43 
     | 
    
         
            +
                            match = fieldsRX.exec(input);
         
     | 
| 
      
 44 
     | 
    
         
            +
                        }
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                        if(titles.length != widths.length && widths.length != 0 ){
         
     | 
| 
      
 47 
     | 
    
         
            +
                            outPut = 'Cols number '+widths.length+" doesn't match headers "+titles.length;
         
     | 
| 
      
 48 
     | 
    
         
            +
                        }else{
         
     | 
| 
      
 49 
     | 
    
         
            +
                            for(var i=0; i < titles.length; i++ ){
         
     | 
| 
      
 50 
     | 
    
         
            +
                                var colObj = '{';
         
     | 
| 
      
 51 
     | 
    
         
            +
                                if(fields[i]){
         
     | 
| 
      
 52 
     | 
    
         
            +
                                    colObj += ':sort_field=>"' + fields[i] + '", '
         
     | 
| 
      
 53 
     | 
    
         
            +
                                }else{
         
     | 
| 
      
 54 
     | 
    
         
            +
                                    colObj += ':disabled=>true, ';
         
     | 
| 
      
 55 
     | 
    
         
            +
                                }
         
     | 
| 
      
 56 
     | 
    
         
            +
                                if(titles[i]){
         
     | 
| 
      
 57 
     | 
    
         
            +
                                    colObj += ':title=>"' + titles[i] + '", '
         
     | 
| 
      
 58 
     | 
    
         
            +
                                }
         
     | 
| 
      
 59 
     | 
    
         
            +
                                if(widths[i]){
         
     | 
| 
      
 60 
     | 
    
         
            +
                                    colObj += ':style=>"width:' + widths[i] + '", '
         
     | 
| 
      
 61 
     | 
    
         
            +
                                }
         
     | 
| 
      
 62 
     | 
    
         
            +
                                colObj = colObj.replace(/(,\s*)$/, '');
         
     | 
| 
      
 63 
     | 
    
         
            +
                                colObj+='}, \n';
         
     | 
| 
      
 64 
     | 
    
         
            +
                                outPut+= colObj;
         
     | 
| 
      
 65 
     | 
    
         
            +
                            }
         
     | 
| 
      
 66 
     | 
    
         
            +
                        }
         
     | 
| 
      
 67 
     | 
    
         
            +
                        outPut = outPut.replace(/,(\s)+$/, '');
         
     | 
| 
      
 68 
     | 
    
         
            +
                        $('#outputField').val(outPut);
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    }
         
     | 
| 
      
 71 
     | 
    
         
            +
                })
         
     | 
| 
      
 72 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 73 
     | 
    
         
            +
            <input id='convertBtn' type="button" value="Convert"/>
         
     | 
| 
      
 74 
     | 
    
         
            +
            <br/>
         
     | 
| 
      
 75 
     | 
    
         
            +
            <textarea id="inputField" style="height: 600px; width:45%;"></textarea>
         
     | 
| 
      
 76 
     | 
    
         
            +
            <textarea id="outputField" style="height: 600px; width:45%;"></textarea>
         
     | 
| 
      
 77 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 78 
     | 
    
         
            +
            </html>
         
     | 
| 
         @@ -0,0 +1,114 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <!DOCTYPE html>
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 4 
     | 
    
         
            +
            <head>
         
     | 
| 
      
 5 
     | 
    
         
            +
            <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            <title>Table of Contents - RDoc Documentation</title>
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            <script type="text/javascript">
         
     | 
| 
      
 12 
     | 
    
         
            +
              var rdoc_rel_prefix = "./";
         
     | 
| 
      
 13 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            <script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
         
     | 
| 
      
 16 
     | 
    
         
            +
            <script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
         
     | 
| 
      
 17 
     | 
    
         
            +
            <script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
         
     | 
| 
      
 18 
     | 
    
         
            +
            <script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
         
     | 
| 
      
 19 
     | 
    
         
            +
            <script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
         
     | 
| 
      
 20 
     | 
    
         
            +
            <script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            <body class="indexpage">
         
     | 
| 
      
 24 
     | 
    
         
            +
            <h1>Table of Contents - RDoc Documentation</h1>
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            <h2>Pages</h2>
         
     | 
| 
      
 27 
     | 
    
         
            +
            <ul>
         
     | 
| 
      
 28 
     | 
    
         
            +
              <li class="file">
         
     | 
| 
      
 29 
     | 
    
         
            +
                <a href="README_rdoc.html">README</a>
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                <img class="toc-toggle" src="images/transparent.png" alt="" title="toggle headings">
         
     | 
| 
      
 32 
     | 
    
         
            +
                <ul class="initially-hidden">
         
     | 
| 
      
 33 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-SortableSkima">SortableSkima</a>
         
     | 
| 
      
 34 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Description">Description</a>
         
     | 
| 
      
 35 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Installation">Installation</a>
         
     | 
| 
      
 36 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Tables">Tables</a>
         
     | 
| 
      
 37 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Example+usage">Example usage</a>
         
     | 
| 
      
 38 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Method+sortable_table_tag%28+base_query%2C+columns%3D%5B%5D%2C+opts%3D%7B%7D+%29">Method sortable_table_tag( base_query, columns=[], opts={} )</a>
         
     | 
| 
      
 39 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Filters">Filters</a>
         
     | 
| 
      
 40 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Example">Example</a>
         
     | 
| 
      
 41 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Method+sortable_filter_tag%28column_name%2C+options_list%2C++opts+%3D+%7B%7D%29">Method sortable_filter_tag(column_name, options_list,  opts = {})</a>
         
     | 
| 
      
 42 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Frontend">Frontend</a>
         
     | 
| 
      
 43 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-Re-using+sortable+filters+and+orders">Re-using sortable filters and orders</a>
         
     | 
| 
      
 44 
     | 
    
         
            +
                  <li><a href="README_rdoc.html#label-EXTRA%3A+How+to+generate+a+gem+for+www.gems.skima.net">EXTRA: How to generate a gem for <a href="http://www.gems.skima.net">www.gems.skima.net</a></a>
         
     | 
| 
      
 45 
     | 
    
         
            +
                </ul>
         
     | 
| 
      
 46 
     | 
    
         
            +
              </li>
         
     | 
| 
      
 47 
     | 
    
         
            +
              
         
     | 
| 
      
 48 
     | 
    
         
            +
            </ul>
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            <h2 id="classes">Classes/Modules</h2>
         
     | 
| 
      
 51 
     | 
    
         
            +
            <ul>
         
     | 
| 
      
 52 
     | 
    
         
            +
              <li class="module">
         
     | 
| 
      
 53 
     | 
    
         
            +
                <a href="SortableSkima.html">SortableSkima</a>
         
     | 
| 
      
 54 
     | 
    
         
            +
              </li>
         
     | 
| 
      
 55 
     | 
    
         
            +
                <li class="class">
         
     | 
| 
      
 56 
     | 
    
         
            +
                <a href="SortableSkima/Engine.html">SortableSkima::Engine</a>
         
     | 
| 
      
 57 
     | 
    
         
            +
              </li>
         
     | 
| 
      
 58 
     | 
    
         
            +
                <li class="class">
         
     | 
| 
      
 59 
     | 
    
         
            +
                <a href="Backtrace.html">Backtrace</a>
         
     | 
| 
      
 60 
     | 
    
         
            +
              </li>
         
     | 
| 
      
 61 
     | 
    
         
            +
                <li class="module">
         
     | 
| 
      
 62 
     | 
    
         
            +
                <a href="SortableHelper.html">SortableHelper</a>
         
     | 
| 
      
 63 
     | 
    
         
            +
              </li>
         
     | 
| 
      
 64 
     | 
    
         
            +
              
         
     | 
| 
      
 65 
     | 
    
         
            +
            </ul>
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            <h2 id="methods">Methods</h2>
         
     | 
| 
      
 68 
     | 
    
         
            +
            <ul>
         
     | 
| 
      
 69 
     | 
    
         
            +
              
         
     | 
| 
      
 70 
     | 
    
         
            +
                <li class="method"><a href="SortableSkima.html#method-c-attach_filters">::attach_filters — SortableSkima</a>
         
     | 
| 
      
 71 
     | 
    
         
            +
              
         
     | 
| 
      
 72 
     | 
    
         
            +
                <li class="method"><a href="SortableSkima.html#method-c-attach_orders">::attach_orders — SortableSkima</a>
         
     | 
| 
      
 73 
     | 
    
         
            +
              
         
     | 
| 
      
 74 
     | 
    
         
            +
                <li class="method"><a href="SortableSkima.html#method-c-attach_sortables">::attach_sortables — SortableSkima</a>
         
     | 
| 
      
 75 
     | 
    
         
            +
              
         
     | 
| 
      
 76 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-c-clear_old_records">::clear_old_records — Backtrace</a>
         
     | 
| 
      
 77 
     | 
    
         
            +
              
         
     | 
| 
      
 78 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-c-for_token">::for_token — Backtrace</a>
         
     | 
| 
      
 79 
     | 
    
         
            +
              
         
     | 
| 
      
 80 
     | 
    
         
            +
                <li class="method"><a href="SortableSkima.html#method-c-root">::root — SortableSkima</a>
         
     | 
| 
      
 81 
     | 
    
         
            +
              
         
     | 
| 
      
 82 
     | 
    
         
            +
                <li class="method"><a href="SortableSkima.html#method-c-setup">::setup — SortableSkima</a>
         
     | 
| 
      
 83 
     | 
    
         
            +
              
         
     | 
| 
      
 84 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-get_filters">#get_filters — Backtrace</a>
         
     | 
| 
      
 85 
     | 
    
         
            +
              
         
     | 
| 
      
 86 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-get_order">#get_order — Backtrace</a>
         
     | 
| 
      
 87 
     | 
    
         
            +
              
         
     | 
| 
      
 88 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-get_page">#get_page — Backtrace</a>
         
     | 
| 
      
 89 
     | 
    
         
            +
              
         
     | 
| 
      
 90 
     | 
    
         
            +
                <li class="method"><a href="SortableHelper.html#method-i-get_sortable">#get_sortable — SortableHelper</a>
         
     | 
| 
      
 91 
     | 
    
         
            +
              
         
     | 
| 
      
 92 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-parsed_sortables">#parsed_sortables — Backtrace</a>
         
     | 
| 
      
 93 
     | 
    
         
            +
              
         
     | 
| 
      
 94 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-set_filters">#set_filters — Backtrace</a>
         
     | 
| 
      
 95 
     | 
    
         
            +
              
         
     | 
| 
      
 96 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-set_order">#set_order — Backtrace</a>
         
     | 
| 
      
 97 
     | 
    
         
            +
              
         
     | 
| 
      
 98 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-set_page">#set_page — Backtrace</a>
         
     | 
| 
      
 99 
     | 
    
         
            +
              
         
     | 
| 
      
 100 
     | 
    
         
            +
                <li class="method"><a href="SortableHelper.html#method-i-sortable_filter_tag">#sortable_filter_tag — SortableHelper</a>
         
     | 
| 
      
 101 
     | 
    
         
            +
              
         
     | 
| 
      
 102 
     | 
    
         
            +
                <li class="method"><a href="SortableHelper.html#method-i-sortable_table_tag">#sortable_table_tag — SortableHelper</a>
         
     | 
| 
      
 103 
     | 
    
         
            +
              
         
     | 
| 
      
 104 
     | 
    
         
            +
                <li class="method"><a href="Backtrace.html#method-i-update_sortables">#update_sortables — Backtrace</a>
         
     | 
| 
      
 105 
     | 
    
         
            +
              
         
     | 
| 
      
 106 
     | 
    
         
            +
            </ul>
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            <footer id="validator-badges">
         
     | 
| 
      
 110 
     | 
    
         
            +
              <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
         
     | 
| 
      
 111 
     | 
    
         
            +
              <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.12.2.
         
     | 
| 
      
 112 
     | 
    
         
            +
              <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
         
     | 
| 
      
 113 
     | 
    
         
            +
            </footer>
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,122 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SortableSkima
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Our host application root path
         
     | 
| 
      
 3 
     | 
    
         
            +
              # We set this when the engine is initialized
         
     | 
| 
      
 4 
     | 
    
         
            +
              mattr_accessor :app_root
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              # Yield self on setup for nice config blocks
         
     | 
| 
      
 7 
     | 
    
         
            +
              def self.setup
         
     | 
| 
      
 8 
     | 
    
         
            +
                yield self
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def self.root
         
     | 
| 
      
 12 
     | 
    
         
            +
                File.expand_path '../..', __FILE__
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def self.attach_filters query, filters, srtbl
         
     | 
| 
      
 16 
     | 
    
         
            +
                unless filters.blank?
         
     | 
| 
      
 17 
     | 
    
         
            +
                  filters.each_key do |filter_key|
         
     | 
| 
      
 18 
     | 
    
         
            +
                    filter_val = filters[filter_key]
         
     | 
| 
      
 19 
     | 
    
         
            +
                    if filter_val
         
     | 
| 
      
 20 
     | 
    
         
            +
                      filter_obj = srtbl.filters()[filter_key.to_i]
         
     | 
| 
      
 21 
     | 
    
         
            +
                      filter_val = filter_obj[:options][filter_val.to_i]
         
     | 
| 
      
 22 
     | 
    
         
            +
                      unless ['Todos','todos','',"All", "all"].include?(filter_val)
         
     | 
| 
      
 23 
     | 
    
         
            +
                        if filter_obj[:raw_sql]
         
     | 
| 
      
 24 
     | 
    
         
            +
                          query = query.where(filter_val)
         
     | 
| 
      
 25 
     | 
    
         
            +
                        else
         
     | 
| 
      
 26 
     | 
    
         
            +
                          query = query.where(filter_obj[:column_name]=>filter_val)
         
     | 
| 
      
 27 
     | 
    
         
            +
                        end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
                query
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def self.attach_orders query, orders, srtbl
         
     | 
| 
      
 37 
     | 
    
         
            +
                order_for_client = false
         
     | 
| 
      
 38 
     | 
    
         
            +
                orders_ar = (orders || '').split ','
         
     | 
| 
      
 39 
     | 
    
         
            +
                orders_ar.each do |new_order|
         
     | 
| 
      
 40 
     | 
    
         
            +
                  order_for_client = new_order unless order_for_client != false
         
     | 
| 
      
 41 
     | 
    
         
            +
                  new_order = new_order.split ' '
         
     | 
| 
      
 42 
     | 
    
         
            +
                  order_by = (srtbl.columns_queries()[new_order[0].to_i][:sort_field] + " #{new_order[1]}") if new_order[0]
         
     | 
| 
      
 43 
     | 
    
         
            +
                  if order_by
         
     | 
| 
      
 44 
     | 
    
         
            +
                    query = query.order( order_by)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
               return query, order_for_client
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def self.attach_sortables query, sortable_id, cur_user_or_admin, include_order = false #, include_page = false
         
     | 
| 
      
 51 
     | 
    
         
            +
                srtbl = Sortable.find_by_id(sortable_id)
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                return if srtbl.blank?
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                query = eval(srtbl.base_query) if query.nil? || query == :base
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                backtrace = Backtrace.for_token(srtbl.token, cur_user_or_admin)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                filters = backtrace.get_filters
         
     | 
| 
      
 60 
     | 
    
         
            +
                orders = backtrace.get_order
         
     | 
| 
      
 61 
     | 
    
         
            +
                #page = backtrace.get_page
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                orders = srtbl.options[:default_order] if orders.blank?
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                query = SortableSkima::attach_filters query, filters, srtbl
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                query = SortableSkima::attach_orders( query, orders, srtbl) if include_order
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                query
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
              #module ActiveRecord
         
     | 
| 
      
 72 
     | 
    
         
            +
                # makes a Relation look like SortableSkima::Collection
         
     | 
| 
      
 73 
     | 
    
         
            +
              #end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            #TODO get all these methods working in ActiveSupport so they can be used like User.sortable_shit.order(bla bla).more_sortable_shit
         
     | 
| 
      
 77 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 78 
     | 
    
         
            +
            module Fucka
         
     | 
| 
      
 79 
     | 
    
         
            +
              def self.included(base)
         
     | 
| 
      
 80 
     | 
    
         
            +
                base.class_eval do
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                   # extend ActiveSupport::Concern
         
     | 
| 
      
 83 
     | 
    
         
            +
                    def self.sortable_conds sortable_id, cur_user_or_admin, include_order = false #, include_page = false
         
     | 
| 
      
 84 
     | 
    
         
            +
                      srtbl = Sortable.find_by_id(sortable_id)
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                      return if srtbl.blank?
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                      backtrace = Backtrace.for_token(srtbl.token, cur_user_or_admin)
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                      filters = backtrace.get_filters
         
     | 
| 
      
 91 
     | 
    
         
            +
                      orders = backtrace.get_order
         
     | 
| 
      
 92 
     | 
    
         
            +
                      page = backtrace.get_page
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                      orders = srtbl.options[:default_order] if orders.blank?
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                      query = SortableSkima::attach_filters self, filters, srtbl
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                      query = SortableSkima::attach_orders( self, orders, srtbl) if include_order
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      puts "hello passed test #{query}"
         
     | 
| 
      
 101 
     | 
    
         
            +
                      query
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            ActiveRecord::Base.send(:include, Fucka)
         
     | 
| 
      
 108 
     | 
    
         
            +
            =end
         
     | 
| 
      
 109 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            require 'sortable_skima/backtrace.rb'
         
     | 
| 
      
 112 
     | 
    
         
            +
            #require 'sortable_skima/active_record.rb'
         
     | 
| 
      
 113 
     | 
    
         
            +
            require 'sortable_skima/engine.rb'
         
     | 
| 
      
 114 
     | 
    
         
            +
            #require 'sortable_skima/action_controller.rb'
         
     | 
| 
      
 115 
     | 
    
         
            +
            require 'sortable_skima/helpers/sortable_helper.rb'
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            ActionView::Base.send :include, SortableHelper
         
     | 
| 
      
 118 
     | 
    
         
            +
            #ActionController::Base.send :include SortableControllerExtension
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            #ActiveSupport.on_load(:action_controller) do
         
     | 
| 
      
 121 
     | 
    
         
            +
             # include Foo
         
     | 
| 
      
 122 
     | 
    
         
            +
            #end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 2 
     | 
    
         
            +
            module ActiveRecordExtension
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              extend ActiveSupport::Concern
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              module ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                # @return [SQL value replacement for column]
         
     | 
| 
      
 9 
     | 
    
         
            +
                #Override this in active_record subclasses to costumize filters
         
     | 
| 
      
 10 
     | 
    
         
            +
                #example 'Aberto' --> ' status != fechado'
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                #This can be used for joined columns as well IE: model.joinedModel.columnName
         
     | 
| 
      
 13 
     | 
    
         
            +
                def sortable_custom_filters column, value
         
     | 
| 
      
 14 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def sortable_filters column, value
         
     | 
| 
      
 18 
     | 
    
         
            +
                  out_ar = sortable_custom_filters value, column
         
     | 
| 
      
 19 
     | 
    
         
            +
                  if out_ar.nil? && ([value].flatten & ["Todos", "todos", "All", "all"]).empty?
         
     | 
| 
      
 20 
     | 
    
         
            +
                    if self.column_names.include? column
         
     | 
| 
      
 21 
     | 
    
         
            +
                      if value.kind_of?(Array) && value.length > 1
         
     | 
| 
      
 22 
     | 
    
         
            +
                        out_ar = ["#{column} IN (?)",value]
         
     | 
| 
      
 23 
     | 
    
         
            +
                      else
         
     | 
| 
      
 24 
     | 
    
         
            +
                        out_ar = ["#{column} = ?",value]
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  out_ar
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            # include the extension
         
     | 
| 
      
 35 
     | 
    
         
            +
            ActiveRecord::Base.send(:include, ActiveRecordExtension)#this is a fancy monkey patch as far as I care
         
     | 
| 
      
 36 
     | 
    
         
            +
            =end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #require 'JSON'
         
     | 
| 
      
 2 
     | 
    
         
            +
            #module SortableBacktrace
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Backtrace < ActiveRecord::Base #TODO this should be an extension of Backtrace and not a patch I think
         
     | 
| 
      
 4 
     | 
    
         
            +
                belongs_to :user
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                KEEP_FOR = 3.months
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def self.clear_old_records
         
     | 
| 
      
 9 
     | 
    
         
            +
                  self.where("updated_at < #{Date.today - KEEP_FOR}").destroy_all
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def self.for_token token, user
         
     | 
| 
      
 13 
     | 
    
         
            +
                  user_id = user.id
         
     | 
| 
      
 14 
     | 
    
         
            +
                  self.where(:action=>token,:user_id=>user_id).first || self.create(:action=>token,:user_id=>user_id)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def parsed_sortables
         
     | 
| 
      
 18 
     | 
    
         
            +
                  if @parsed_sortables.nil?
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @parsed_sortables = JSON.parse(value || '{}')
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @parsed_sortables
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def get_order
         
     | 
| 
      
 25 
     | 
    
         
            +
                  parsed_sortables['order']
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
                def get_filters
         
     | 
| 
      
 28 
     | 
    
         
            +
                  parsed_sortables['filters']
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                def get_page
         
     | 
| 
      
 31 
     | 
    
         
            +
                  parsed_sortables['page']
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def set_order new_order
         
     | 
| 
      
 35 
     | 
    
         
            +
                  parsed_sortables['order'] = new_order
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
                def set_filters new_filters
         
     | 
| 
      
 38 
     | 
    
         
            +
                  parsed_sortables['filters'] = new_filters
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                def set_page new_page
         
     | 
| 
      
 41 
     | 
    
         
            +
                  parsed_sortables['page'] = new_page
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def update_sortables n_filters = nil , n_order = nil, n_page = nil
         
     | 
| 
      
 45 
     | 
    
         
            +
                  set_filters n_filters unless n_filters.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                  set_order n_order unless n_order.nil?
         
     | 
| 
      
 47 
     | 
    
         
            +
                  set_page n_page unless n_page.nil?
         
     | 
| 
      
 48 
     | 
    
         
            +
                  self.update_attribute :value, parsed_sortables.to_json
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            #end
         
     | 
| 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 2 
     | 
    
         
            +
            $app_ref = nil
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module SortableSkima
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              class Engine < ::Rails::Engine
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                # requires all dependencies
         
     | 
| 
      
 9 
     | 
    
         
            +
               #Gem.loaded_specs['SortableSkima'].dependencies.each do |d|
         
     | 
| 
      
 10 
     | 
    
         
            +
               #   require d.name
         
     | 
| 
      
 11 
     | 
    
         
            +
               # end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                config.after_initialize do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #require files to run after main app initialization is finished. 
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #require 'acc_skima/acc_skima_post_init_config'
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
               # assets_dir = File.expand_path( File.dirname(__FILE__) + '/../../app/assets/**/*' )
         
     | 
| 
      
 20 
     | 
    
         
            +
               # initializer "assets_precompile" do |app|
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #puts "ADDING PRECOMPILE TO FILES IN #{assets_dir}"
         
     | 
| 
      
 22 
     | 
    
         
            +
               #   Dir[assets_dir+'*.{js,css,html,png,gif,jpg}'].each do |file|
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #  puts "ADDING TO FILE  #{file}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                    #app.config.assets.precompile << file.split('javascripts/').last
         
     | 
| 
      
 25 
     | 
    
         
            +
               #   end
         
     | 
| 
      
 26 
     | 
    
         
            +
               # end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                # Initializer to combine this engines static assets with the static assets of the hosting site.
         
     | 
| 
      
 29 
     | 
    
         
            +
                initializer "static assets" do |app|
         
     | 
| 
      
 30 
     | 
    
         
            +
                  assets_path = "#{root}/app/assets"
         
     | 
| 
      
 31 
     | 
    
         
            +
                  puts "===Sortable_skima: initializing!==="
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  #app.middleware.insert_before(ActiveSupport::Cache::Strategy::LocalCache,::ActionDispatch::Static, assets_path)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  app.middleware.use(::ActionDispatch::Static, assets_path)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  js_assets_dir = File.expand_path( File.dirname(__FILE__) + '/../../app/assets/javascripts/*' )
         
     | 
| 
      
 36 
     | 
    
         
            +
                  js_files = []
         
     | 
| 
      
 37 
     | 
    
         
            +
                  Dir[js_assets_dir+'*.{js}'].each do |file|
         
     | 
| 
      
 38 
     | 
    
         
            +
                    js_files<< file.split('/').last
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  puts "===Sortable_skima: adding js files to defaults!=== #{js_files.join(' - ')} ==="
         
     | 
| 
      
 41 
     | 
    
         
            +
                  ActionView::Helpers::AssetTagHelper.register_javascript_expansion(
         
     | 
| 
      
 42 
     | 
    
         
            +
                      :defaults=> js_files   #%w(jquery-ui.min.js jquery.ba-bbq.js skima-sortable-tables_2_0_7.js)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  )
         
     | 
| 
      
 44 
     | 
    
         
            +
                 # end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
               # initializer :append_migrations do |app|
         
     | 
| 
      
 48 
     | 
    
         
            +
               #   unless app.root.to_s.match root.to_s
         
     | 
| 
      
 49 
     | 
    
         
            +
                  #  app.config.paths["db/migrate"] += config.paths["db/migrate"].expanded
         
     | 
| 
      
 50 
     | 
    
         
            +
               #   end
         
     | 
| 
      
 51 
     | 
    
         
            +
            #    end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
             
     |