WordPress.org

Plugin Directory

Changeset 597398


Ignore:
Timestamp:
09/11/12 08:53:29 (5 years ago)
Author:
giorgio79
Message:
 
Location:
proofread-bot/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • proofread-bot/trunk/classes/proofread_bot_api.php

    r594952 r597398  
    22 
    33function proofread_bot_check_api($text) { 
     4    $text = htmlentities($text); 
     5    //print_r($text); 
     6    //die; 
    47 
    58    $options = get_option('proofread_bot_options'); 
  • proofread-bot/trunk/proofread_bot.php

    r597138 r597398  
    11<?php 
    22/* 
    3 Plugin Name: Proofread Bot 
    4 Plugin URI: http://proofreadbot.com 
    5 Description: Plagiarism and Duplicate Content Detection - Check your content for duplication and plagiarism straight from your Wordpress admin 
    6 Version: 2.04 
    7 Author: Gyorgy Chityil 
    8 Author URI: http://proofreadbot.com 
    9 */ 
     3        Plugin Name: Proofread Bot 
     4        Plugin URI: http://proofreadbot.com 
     5        Description: Plagiarism and Duplicate Content Detection - Check your content for duplication and plagiarism straight from your Wordpress admin 
     6        Version: 2.05 
     7        Author: Gyorgy Chityil 
     8        Author URI: http://proofreadbot.com 
     9    */ 
    1010 
    1111include('classes/proofread_bot_api.php'); 
     
    1515 
    1616/* 
    17  *  Load necessary include files 
    18  */ 
     17        *  Load necessary include files 
     18    */ 
    1919include( 'config-options.php' ); 
    2020include( 'utils.php' ); 
    2121include( 'proxy.php' ); 
    2222/* 
    23  *  Code to update the toolbar with the AtD Button and Install the AtD TinyMCE Plugin 
    24  */ 
     23        *  Code to update the toolbar with the AtD Button and Install the AtD TinyMCE Plugin 
     24    */ 
    2525function proofread_bot_addbuttons() { 
    26  
     26     
    2727    /* Don't bother doing this stuff if the current user lacks permissions */ 
    28     if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) 
    29         return; 
    30  
     28    if ( ! current_user_can('edit_posts') && !current_user_can('edit_pages') ) 
     29    return; 
     30     
    3131    /* Add only in Rich Editor mode w/ Blog language ID set to English */ 
    3232    if ( get_user_option('rich_editing') == 'true' ) { 
     
    3434        add_filter( 'mce_buttons', 'register_proofread_bot_button' ); 
    3535    } 
    36  
     36     
    3737    add_action( 'personal_options_update', 'proofread_bot_process_options_update' ); 
    3838    add_action( 'personal_options_update', 'proofread_bot_process_unignore_update' ); 
     
    4242 
    4343/* 
    44  * Hook into the TinyMCE buttons and replace the current spellchecker 
    45  */ 
    46 function register_proofread_bot_button( $buttons ) { 
    47  
     44        * Hook into the TinyMCE buttons and replace the current spellchecker 
     45    */ 
     46function register_proofread_bot_button( $buttons )  
     47{ 
     48     
    4849    /* kill the spellchecker.. don't need no steenkin PHP spell checker */ 
    4950    foreach ( $buttons as $key => $button ) { 
     
    5354        } 
    5455    } 
    55  
     56     
    5657    /* hrm... ok add us last plz */ 
    5758    array_push( $buttons, 'separator', 'proofread_bot' ); 
     
    6061 
    6162/* 
    62  * Load the TinyMCE plugin : editor_plugin.js (wp2.5) 
    63  */ 
     63        * Load the TinyMCE plugin : editor_plugin.js (wp2.5) 
     64    */ 
    6465function add_proofread_bot_tinymce_plugin( $plugin_array ) { 
    6566    $plugin_array['proofread_bot'] = WP_PLUGIN_URL . '/proofread-bot/tinymce/editor_plugin.js'; 
     
    6869 
    6970/* 
    70  * Update the TinyMCE init block with proofread_bot specific settings 
    71  */ 
     71        * Update the TinyMCE init block with proofread_bot specific settings 
     72    */ 
    7273function proofread_bot_change_mce_settings( $init_array ) { 
    73  
    74         /* grab our user and validate their existence */ 
    75         $user = wp_get_current_user(); 
    76         if ( ! $user || $user->ID == 0 ) 
    77                 return; 
    78  
     74     
     75    /* grab our user and validate their existence */ 
     76    $user = wp_get_current_user(); 
     77    if ( ! $user || $user->ID == 0 ) 
     78    return; 
     79     
    7980    $init_array['proofread_bot_rpc_url']        = admin_url() . 'admin-ajax.php?action=proxy_proofread_bot&url='; 
    8081    $init_array['proofread_bot_ignore_rpc_url'] = admin_url() . 'admin-ajax.php?action=proofread_bot_ignore&phrase='; 
     
    8687    $init_array['proofread_bot_show_types']     = proofread_bot_get_setting( $user->ID, 'proofread_bot_options' ); 
    8788    $init_array['gecko_spellcheck']   = 'false'; 
    88  
     89     
    8990    return $init_array; 
    9091} 
     
    9394 
    9495/* 
    95  * Sanitizes proofread_bot AJAX data to acceptable chars, caller needs to make sure ' is escaped 
    96  */ 
     96        * Sanitizes proofread_bot AJAX data to acceptable chars, caller needs to make sure ' is escaped 
     97    */ 
    9798function proofread_bot_sanitize( $untrusted ) { 
    98         return preg_replace( '/[^a-zA-Z0-9\-\',_ ]/i', "", $untrusted ); 
    99 } 
    100  
    101 /* 
    102  * proofread_bot HTML Editor Stuff 
    103  */ 
     99    return preg_replace( '/[^a-zA-Z0-9\-\',_ ]/i', "", $untrusted ); 
     100} 
     101 
     102/* 
     103        * proofread_bot HTML Editor Stuff 
     104    */ 
    104105 
    105106function proofread_bot_settings() { 
    106107    $user = wp_get_current_user(); 
    107  
     108     
    108109    header( 'Content-Type: text/javascript' ); 
    109  
     110     
    110111    /* set the RPC URL for proofread_bot */ 
    111112    echo "proofread_bot.rpc = '" . admin_url() . "admin-ajax.php?action=proxy_proofread_bot&url=';\n"; 
    112  
     113     
    113114    /* set the API key for proofread_bot */ 
    114115    echo "proofread_bot.api_key = 'WPORG-" . md5(get_bloginfo('wpurl')) . "';\n"; 
    115  
     116     
    116117    /* set the ignored phrases for proofread_bot */ 
    117118    echo "proofread_bot.setIgnoreStrings('" . str_replace( "'", "\\'", proofread_bot_get_setting( $user->ID, 'proofread_bot_ignored_phrases' ) ) . "');\n"; 
    118  
     119     
    119120    /* honor the types we want to show */ 
    120121    echo "proofread_bot.showTypes('" . str_replace( "'", "\\'", proofread_bot_get_setting( $user->ID, 'proofread_bot_options' ) ) ."');\n"; 
    121  
    122         /* this is not an proofread_bot/jQuery setting but I'm putting it in proofread_bot to make it easy for the non-viz plugin to find it */ 
     122     
     123    /* this is not an proofread_bot/jQuery setting but I'm putting it in proofread_bot to make it easy for the non-viz plugin to find it */ 
    123124    echo "proofread_bot.rpc_ignore = '" . admin_url() . "admin-ajax.php?action=proofread_bot_ignore&phrase=';\n"; 
    124  
    125         die; 
     125     
     126    die; 
    126127} 
    127128 
    128129function proofread_bot_load_javascripts() { 
    129         global $pagenow; 
    130  
     130    global $pagenow; 
     131     
    131132    if ( proofread_bot_should_load_on_page() ) { 
    132133        wp_enqueue_script( 'proofread_bot_core', WP_PLUGIN_URL . '/proofread-bot/proofread_bot.core.js', array() ); 
    133             //wp_enqueue_script( 'proofread_bot_quicktags', WP_PLUGIN_URL . '/proofread-bot/proofread_bot-nonvis-editor-plugin.js', array('quicktags') ); 
    134             //wp_enqueue_script( 'proofread_bot_jquery', WP_PLUGIN_URL . '/proofread-bot/jquery.proofread_bot.js', array('jquery') ); 
    135             //wp_enqueue_script( 'proofread_bot_settings', admin_url() . 'admin-ajax.php?action=proofread_bot_settings', array('proofread_bot_jquery') ); 
     134        //wp_enqueue_script( 'proofread_bot_quicktags', WP_PLUGIN_URL . '/proofread-bot/proofread_bot-nonvis-editor-plugin.js', array('quicktags') ); 
     135        //wp_enqueue_script( 'proofread_bot_jquery', WP_PLUGIN_URL . '/proofread-bot/jquery.proofread_bot.js', array('jquery') ); 
     136        //wp_enqueue_script( 'proofread_bot_settings', admin_url() . 'admin-ajax.php?action=proofread_bot_settings', array('proofread_bot_jquery') ); 
    136137        //wp_enqueue_script( 'proofread_bot_autoproofread', WP_PLUGIN_URL . '/proofread-bot/proofread_bot-autoproofread.js', array('proofread_bot_jquery') ); 
    137138    } 
     
    142143function proofread_bot_load_submit_check_javascripts() { 
    143144    global $pagenow; 
    144  
     145     
    145146    $user = wp_get_current_user(); 
    146147    if ( ! $user || $user->ID == 0 ) 
    147         return; 
    148  
     148    return; 
     149     
    149150    if ( proofread_bot_should_load_on_page() ) { 
    150151        $proofread_bot_check_when = proofread_bot_get_setting( $user->ID, 'proofread_bot_check_when' ); 
     
    163164 
    164165function proofread_bot_is_allowed() { 
    165         $user = wp_get_current_user(); 
    166         if ( ! $user || $user->ID == 0 ) 
    167                 return; 
    168  
    169         if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) 
    170                 return; 
    171  
    172         return 1; 
     166    $user = wp_get_current_user(); 
     167    if ( ! $user || $user->ID == 0 ) 
     168    return; 
     169     
     170    if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) 
     171    return; 
     172     
     173    return 1; 
    173174} 
    174175 
    175176function proofread_bot_load_css() { 
    176177    if ( proofread_bot_should_load_on_page() ) 
    177             wp_enqueue_style( 'proofread_bot_style', WP_PLUGIN_URL . '/proofread-bot/proofread_bot.css', null, '1.0', 'screen' ); 
     178    wp_enqueue_style( 'proofread_bot_style', WP_PLUGIN_URL . '/proofread-bot/proofread_bot.css', null, '1.0', 'screen' ); 
    178179} 
    179180 
     
    181182function proofread_bot_should_load_on_page() { 
    182183    global $pagenow; 
    183  
     184     
    184185    $pages = array('post.php', 'post-new.php', 'page.php', 'page-new.php', 'admin.php', 'profile.php'); 
    185  
     186     
    186187    if( in_array($pagenow, $pages) ) 
    187         return true; 
    188  
     188    return true; 
     189     
    189190    return false; 
    190191} 
     
    215216 
    216217/* 
    217 * Set up options, convert old options, add filters if automatic display is enabled, and enqueue scripts 
    218 * @uses get_option, update_option, add_filter, wp_enqueue_script 
    219 * @return null 
    220 */ 
     218        * Set up options, convert old options, add filters if automatic display is enabled, and enqueue scripts 
     219        * @uses get_option, update_option, add_filter, wp_enqueue_script 
     220        * @return null 
     221    */ 
    221222 
    222223/* Define the custom box */ 
     
    226227/* Adds a box to the main column on the Post and Page edit screens */ 
    227228function proofread_bot_add_custom_box() { 
    228  
     229     
    229230    add_meta_box(  
    230231    'proofread_bot', 
     
    244245/* Prints the box content */ 
    245246function proofread_bot_inner_custom_box( $post ) { 
    246  
     247     
    247248    // Use nonce for verification 
    248249    wp_nonce_field( plugin_basename( __FILE__ ), 'proofread_bot_noncename' ); 
    249  
     250     
    250251    // The actual fields for data entry 
    251252    //echo '<label for="proofread_bot_new_field">'; 
     
    256257    echo '<script>         
    257258        jQuery(document).ready(function(){ 
    258  
     259         
    259260        //console.log(tinyMCE.activeEditor.getContent(content)); 
    260      
     261         
    261262        jQuery("#proofread_bot-submit").click(function(event){ 
    262             var proofread_bot_text; 
    263  
    264             // standard tinymce 
    265             if (jQuery("#content_ifr").contents().find("#tinymce").html() !== "") 
    266                 proofread_bot_text = jQuery("#content_ifr").contents().find("#tinymce").html(); 
    267                  
    268             // tinymce advanced 
    269             if (jQuery("#content").html() !== "") 
    270                 proofread_bot_text = jQuery("#content").html(); 
    271              
    272             if (proofread_bot_text === null || proofread_bot_text === ""  || proofread_bot_text === "undefined"  || proofread_bot_text === "<p><br data-mce-bogus=\"1\"></p>" || proofread_bot_text === "<p><br></p>" ) 
    273                 { 
    274                 jQuery("#proofread_bot-submit").after("<br/>Failed to get text from editor, please try switching to \"Visual\" if you use TinyMCE Advanced or report the issue at http://proofreadbot.com/support-forum mentioning your Wysiwyg extension, such as CKEditor etc..."); 
    275                 } 
    276             else 
    277                 { 
    278                 jQuery("#proofread_bot-submit").after("<div id=\"proofread_bot_throbber\"><img src=\"'. WP_PLUGIN_URL.'/proofread-bot/throbber.gif\" /> Fetching report, may take a few seconds...</div>"); 
    279                              
    280                 var data = { 
    281                 action: \'post_check_proofread_bot\', 
    282                 "text": proofread_bot_text 
    283                 }; 
    284  
    285                 // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php 
    286                 jQuery.post(ajaxurl, data, function(response) { 
    287                     jQuery("#proofread_bot-submit").after(response); 
    288                     jQuery("#proofread_bot_throbber").remove();  
    289                 });  
    290                 } 
    291             }); 
     263        var proofread_bot_text; 
     264         
     265        // standard tinymce 
     266        if (jQuery("#content_ifr").contents().find("#tinymce").html() !== "") 
     267        proofread_bot_text = jQuery("#content_ifr").contents().find("#tinymce").html(); 
     268         
     269        // tinymce advanced 
     270        if (jQuery("#content").html() !== "") 
     271        proofread_bot_text = jQuery("#content").html(); 
     272         
     273        if (proofread_bot_text === null || proofread_bot_text === ""  || proofread_bot_text === "undefined"  || proofread_bot_text === "<p><br data-mce-bogus=\"1\"></p>" || proofread_bot_text === "<p><br></p>" ) 
     274        { 
     275        jQuery("#proofread_bot-submit").after("<br/>Failed to get text from editor, please try switching to \"Visual\" if you use TinyMCE Advanced or report the issue at http://proofreadbot.com/support-forum mentioning your Wysiwyg extension, such as CKEditor etc..."); 
     276        } 
     277        else 
     278        { 
     279        jQuery("#proofread_bot-submit").after("<div id=\"proofread_bot_throbber\"><img src=\"'. WP_PLUGIN_URL.'/proofread-bot/throbber.gif\" /> Fetching report, may take a few seconds...</div>"); 
     280         
     281        var data = { 
     282        action: \'post_check_proofread_bot\', 
     283        "text": proofread_bot_text 
     284        }; 
     285         
     286        // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php 
     287        jQuery.post(ajaxurl, data, function(response) { 
     288        jQuery("#proofread_bot-submit").after(response); 
     289        jQuery("#proofread_bot_throbber").remove();  
     290        });  
     291        } 
     292        }); 
    292293        }); 
    293294        </script>'; 
     
    300301{    
    301302    $post = $_POST['text']; 
    302  
     303     
    303304    if(current_user_can('check_proofread_bot')) 
    304305    { 
    305  
     306        //if (strpos($post, "&lt;") !== 'false') 
     307        //  $post = html_entity_decode($post); 
     308         
     309        //print_r($post); 
     310        //die; 
     311         
    306312        $node = proofread_bot_check_api($post); 
    307  
     313         
    308314        print_r($node->display); 
    309315        //echo "IN HERE"; 
    310316    } 
    311  
    312  
     317     
     318     
    313319    die(); 
    314320} 
     
    341347    if( $options[ 'proofread_bot_placement_posts' ] == true)   
    342348    $content = $content . $button; 
    343  
     349     
    344350     
    345351    return $content; 
     
    374380function proofread_botsoptions_init_fn(){ 
    375381    register_setting('proofread_bot_options', 'proofread_bot_options', 'proofread_bot_options_validate' ); 
    376  
     382     
    377383    add_settings_section('main_section', 'Proofread Bot Account Details', 'proofread_bot_section_text_fn', __FILE__); 
    378  
     384     
    379385    add_settings_field('proofread_bot_username', 'Proofread Bot Username', 'proofread_bot_setting_username_fn', __FILE__, 'main_section'); 
    380386    add_settings_field('proofread_bot_password', 'Proofread Bot Password', 'proofread_bot_setting_password_fn', __FILE__, 'main_section'); 
    381387    add_settings_field('min_user_level', 'Lowest Role that can check Proofread Bot', 'proofread_bot_setting_role_fn', __FILE__, 'main_section'); 
    382  
     388     
    383389    add_settings_section('button_section', 'Proofread Bot Button Settings', 'proofread_bot_button_section_text_fn', __FILE__); 
    384  
     390     
    385391    add_settings_field('proofread_bot_button', 'Select Button', 'proofread_bot_setting_button_fn', __FILE__, 'button_section'); 
    386392    add_settings_field('proofread_bot_button_color', 'Select Button Color', 'proofread_bot_setting_button_color_fn', __FILE__, 'button_section'); 
    387393    // add_settings_field('proofread_bot_button_placement_homepage', 'Show button on homepage', 'proofread_bot_setting_button_placement_homepage_fn', __FILE__, 'button_section'); 
    388394    add_settings_field('proofread_bot_button_placement_posts', 'Show button on posts', 'proofread_bot_setting_button_placement_posts_fn', __FILE__, 'button_section'); 
    389  
     395     
    390396    add_settings_section('affiliate_section', 'Proofread Bot Affiliate Program - Make Money', 'proofread_bot_affiliate_section_text_fn', __FILE__); 
    391397    add_settings_field('proofread_bot_affiliate_id', 'Proofread Bot Affiliate Id', 'proofread_bot_setting_affiliate_id_fn', __FILE__, 'affiliate_section'); 
     
    395401    $min_role = $options ? $options['role'] : 'administrator' ; 
    396402    $roles = array('Administrator'=>'administrator', 'Editor'=>'editor', 'Author'=>'author', 'Contributor'=>'contributor'); 
    397  
     403     
    398404    foreach($roles as $role=>$val) 
    399405    { 
    400406        $role = get_role($val); 
    401407        $role->add_cap( 'check_proofread_bot' ); 
    402  
     408         
    403409        if($val == $min_role) 
    404410        break; 
     
    429435    $options = get_option('proofread_bot_options'); 
    430436    $items = array('Administrator'=>'administrator', 'Editor'=>'editor', 'Author'=>'author', 'Contributor'=>'contributor'); 
    431  
     437     
    432438    echo "<select id='proofread_bot_role' name='proofread_bot_options[role]'>"; 
    433  
     439     
    434440    foreach($items as $item=>$value) 
    435441    { 
     
    437443        echo "<option value='$value' $selected>$item</option>"; 
    438444    } 
    439  
     445     
    440446    echo "</select>"; 
    441447} 
     
    473479    $options = get_option('proofread_bot_options'); 
    474480    $items = array('Light'=>'light', 'Dark'=>'dark', 'Green'=>'green', 'Red'=>'red', 'Yellow'=>'yellow', 'Blue'=>'blue'); 
    475  
     481     
    476482    echo "<select id='proofread_bot_button_color' name='proofread_bot_options[proofread_bot_button_color]'>"; 
    477  
     483     
    478484    foreach($items as $item=>$value) 
    479485    { 
     
    481487        echo "<option value='$value' $selected>$item</option>"; 
    482488    } 
    483  
     489     
    484490    echo "</select>"; 
    485491} 
     
    489495    if( $options['proofread_bot_placement_homepage']== true)  
    490496    $checked = 'checked="checked"'; 
    491  
     497     
    492498    echo "<input name='proofread_bot_options[proofread_bot_placement_homepage]' type='checkbox' value='true' $checked />"; 
    493499} 
     
    495501function proofread_bot_setting_button_placement_posts_fn() { 
    496502    $options = get_option('proofread_bot_options'); 
    497  
     503     
    498504    if($options['proofread_bot_placement_posts']== true ) 
    499505    $checked = 'checked="checked"'; 
     
    504510 
    505511// Place in Option List on Settings > Plugins page  
    506 function proofread_bot_actlinks( $links, $file ){ 
     512function proofread_bot_actlinks( $links, $file ) { 
    507513    //Static so we don't call plugin_basename on every plugin row. 
    508514    static $this_plugin; 
  • proofread-bot/trunk/proxy.php

    r595560 r597398  
    3939    parse_str($postText); 
    4040 
     41    //see what's in here 
     42    //print_r($data); 
     43    //die; 
     44     
    4145    $node = proofread_bot_check_api($data); 
    4246     
     
    4650    if ($node->display) 
    4751        { 
    48         $xml .="<display> 
    49                 <![CDATA["; 
    50         $xml .= $node->display; 
    51         $xml .= "]]> 
    52             </display>"; 
     52        $xml .="<display><![CDATA["; 
     53        $xml .= $node->display .= "]]></display>"; 
    5354        $xml .= $node->display_tinymce; 
    5455        } 
    5556    else 
    56         $xml .= "<message> 
    57                 <![CDATA[" 
    58                 .$node."]]> 
    59             </message>"; 
     57        $xml .= "<message><![CDATA[".$node."]]></message>"; 
    6058    $xml .= "</xmldoc>"; 
    6159 
  • proofread-bot/trunk/readme.txt

    r597138 r597398  
    44Requires at least: 2.9 
    55Tested up to: 3.4.1 
    6 Stable tag: 2.04 
     6Stable tag: 2.05 
    77 
    88<a href="http://proofreadbot.com">Proofread Bot</a> automatically checks your content for grammar, style, statistic and plagiarism issues. 
     
    4545 
    4646== Changelog == 
     47 
     48= 2.05 = 
     49Fixing Ajax XML whitespace bug 
     50 
     51 
    4752= 2.04 = 
    4853Small Chrome js bug fix 
  • proofread-bot/trunk/tinymce/editor_plugin.js

    r595954 r597398  
    167167                var newdiv = document.createElement('div'); 
    168168 
    169                 //this "if" for IE9...               
    170             //  if (request.responseXML.getElementsByTagName('display')[0].childNodes[1].nodeValue) 
    171             //      newdiv.innerHTML = request.responseXML.getElementsByTagName('display')[0].childNodes[1].nodeValue; 
    172             //  else 
    173                     newdiv.innerHTML = request.responseXML.getElementsByTagName('display')[0].childNodes[0].nodeValue;   
     169                //this "if" for IE9... 
     170                /*console.log(request.responseXML); 
     171                console.log(request.responseXML.getElementsByTagName('display')[0].childNodes[0]); 
     172                console.log(request.responseXML.getElementsByTagName('display')[0].childNodes[0].nodeValue); 
     173                 
     174                var response_text_0 = request.responseXML.getElementsByTagName('display')[0].childNodes[0].nodeValue; 
     175                console.log(response_text_0.length); 
     176 
     177                console.log(request.responseXML.getElementsByTagName('display')[0].childNodes[1]); 
     178                console.log(request.responseXML.getElementsByTagName('display')[0].childNodes[1].nodeValue); 
     179                var response_text_1 = request.responseXML.getElementsByTagName('display')[0].childNodes[0].nodeValue; 
     180                console.log(response_text_1.length); 
     181                */ 
     182                 
     183                if (typeof(request.responseXML.getElementsByTagName('display')[0].childNodes[0]) !== 'undefined') 
     184                    newdiv.innerHTML = request.responseXML.getElementsByTagName('display')[0].childNodes[0].nodeValue; 
     185                else 
     186                    newdiv.innerHTML = request.responseXML.getElementsByTagName('display')[0].childNodes[1].nodeValue;   
    174187 
    175188               document.getElementById('proofread_bot_result').appendChild(newdiv); 
Note: See TracChangeset for help on using the changeset viewer.