โŒˆโŒ‹ โŽ‡ branch:  freshcode


Check-in [3f972a8ea9]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add /rc page (RecentChanges diff)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3f972a8ea910412d26655f1ebcac3fc4356ebc64
User & Date: mario 2014-08-06 11:00:47
Context
2014-08-06
11:01
Reordered gallery, added Fossies.org check-in: 92ebd481e3 user: mario tags: trunk
11:00
Add /rc page (RecentChanges diff) check-in: 3f972a8ea9 user: mario tags: trunk
2014-08-04
15:59
Externalized update_rules() - which currently just hides previously submitted empty-version project entries. check-in: 6ff5dca6cd user: mario tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to .htaccess.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
RewriteRule  ^projects/([\w-_]+)/releases/(\w+)\.json$  index.php?page=api&name=$1&api=version_%1&id=$2 [L,NS,QSA]
RewriteCond  %{REQUEST_METHOD}  ^(GET|PUT|POST|PUSH)$
RewriteRule  ^projects/([\w-_]+)/urls\.json$  index.php?page=api&name=$1&api=urls [L,NS,QSA] 


#-- Page dispatching
RewriteRule  ^$                 index.php?page=index    [L,NS,QSA]
RewriteRule  ^(projects|submit|search|flag|tags?|feed|login|links|forum|admin|drchangelog)\b/?(\w+(?:[-_]\w+)*)?(?:\.(json|atom|rss))?/?$   index.php?page=$1&name=$2&ext=$3   [L,NS,QSA]

#-- Deny direct invocations
RewriteRule  ^freshcode\.db.*$  -                       [F]
RewriteRule  ^\.                -                       [F]
RewriteCond  %{ENV:REDIRECT_STATUS}  !200
RewriteRule  ^\w+\.php(|/.*)$   -                       [F,L,NS]









|








34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
RewriteRule  ^projects/([\w-_]+)/releases/(\w+)\.json$  index.php?page=api&name=$1&api=version_%1&id=$2 [L,NS,QSA]
RewriteCond  %{REQUEST_METHOD}  ^(GET|PUT|POST|PUSH)$
RewriteRule  ^projects/([\w-_]+)/urls\.json$  index.php?page=api&name=$1&api=urls [L,NS,QSA] 


#-- Page dispatching
RewriteRule  ^$                 index.php?page=index    [L,NS,QSA]
RewriteRule  ^(projects|submit|search|flag|names?|tags?|feed|login|links|forum|rc|admin|drchangelog)\b/?(\w+(?:[-_]\w+)*)?(?:\.(json|atom|rss))?/?$   index.php?page=$1&name=$2&ext=$3   [L,NS,QSA]

#-- Deny direct invocations
RewriteRule  ^freshcode\.db.*$  -                       [F]
RewriteRule  ^\.                -                       [F]
RewriteCond  %{ENV:REDIRECT_STATUS}  !200
RewriteRule  ^\w+\.php(|/.*)$   -                       [F,L,NS]


Changes to freshcode.css.

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * api: css
 * type: stylesheet
 * title: freshcode.club layout+style
 * description: Simulates the late freecode.com layout and looks; well mostly.
 * version: 0.6.2.9
 *
 * Centered two-pane layout. The #main section is usually 33% of the screen width,
 * while the #sidebar floats at the right. They're repositioned only using padding:
 * to the outer html,body{}.
 *
 */






|







1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * api: css
 * type: stylesheet
 * title: freshcode.club layout+style
 * description: Simulates the late freecode.com layout and looks; well mostly.
 * version: 0.6.3.1
 *
 * Centered two-pane layout. The #main section is usually 33% of the screen width,
 * while the #sidebar floats at the right. They're repositioned only using padding:
 * to the outer html,body{}.
 *
 */

47
48
49
50
51
52
53








54
55
56
57
58
59
60
    background: linear-gradient(90deg,#fafafa,#fafaff);
    box-shadow: 0 0 3px 2px #ccf;
    border-radius: 3px;
    margin: 1px;
}
var { box-shadow: 0 0 3px 2px #fdd; }
kbd { box-shadow: 0 0 3px 2px #dfd; }









/**
 * Page header, info bar and logo box
 *
 */
#topbar {
    background: #555599;







>
>
>
>
>
>
>
>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    background: linear-gradient(90deg,#fafafa,#fafaff);
    box-shadow: 0 0 3px 2px #ccf;
    border-radius: 3px;
    margin: 1px;
}
var { box-shadow: 0 0 3px 2px #fdd; }
kbd { box-shadow: 0 0 3px 2px #dfd; }

table {}
tr, th, td {
   align: left;
   vertical-align: top;
}



/**
 * Page header, info bar and logo box
 *
 */
#topbar {
    background: #555599;
97
98
99
100
101
102
103



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118












119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    border-top: 1pt solid #ccc;
    border-radius: 5pt;
    background: #e5e7e9;
    background: linear-gradient(to bottom, #ffffff, #fdfefe, #f5f7f9, #eaecee, #e5e7e9, #e1e3e5, #d0d1d2);
    position: relative;
    top: -15pt;
}



#tools a {
    color: #777;
    margin: 0 1pt;
    padding: 2pt 8pt;
    border-radius: 4pt;
}
#tools a.submit {
    background: #79d;
    background: linear-gradient(145deg,#e5e5ef,#d1d3df);
    color: #111;
}
#tools a:hover {
    color: #fff;
    background: #346;
}












#tools #search_q {
    display: inline;
    border-radius: 4pt;
    padding: 1pt;
}
#tools #search_q input {
    border: 1px solid #999;
    background: #eee;
    height: 11pt;
    border-radius: 3pt;
    margin: 1pt;
}
#tools #search_q:hover {
    background: #567;
}
#tools #search_q:hover a {
    color: #eee;
}

/**
 * Sidebar floats right to #main, usually just a fifth of its width.







>
>
>















>
>
>
>
>
>
>
>
>
>
>
>













|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    border-top: 1pt solid #ccc;
    border-radius: 5pt;
    background: #e5e7e9;
    background: linear-gradient(to bottom, #ffffff, #fdfefe, #f5f7f9, #eaecee, #e5e7e9, #e1e3e5, #d0d1d2);
    position: relative;
    top: -15pt;
}
.absolute {
    position: absolute;
}
#tools a {
    color: #777;
    margin: 0 1pt;
    padding: 2pt 8pt;
    border-radius: 4pt;
}
#tools a.submit {
    background: #79d;
    background: linear-gradient(145deg,#e5e5ef,#d1d3df);
    color: #111;
}
#tools a:hover {
    color: #fff;
    background: #346;
}
#tools .submenu:hover {
    background: #D3D7DE;
    border-radius: 5pt;
}
#tools .submenu a:first-child {
    padding-right: 3pt;
    margin-right: 0;
}
#tools .submenu a:nth-child(2) {
    padding-left: 3pt;
    margin-left: 0;
}
#tools #search_q {
    display: inline;
    border-radius: 4pt;
    padding: 1pt;
}
#tools #search_q input {
    border: 1px solid #999;
    background: #eee;
    height: 11pt;
    border-radius: 3pt;
    margin: 1pt;
}
#tools #search_q:hover {
    background: #D3D7DE;
}
#tools #search_q:hover a {
    color: #eee;
}

/**
 * Sidebar floats right to #main, usually just a fifth of its width.
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
    min-height: 700pt;
}

#main h2, #main h3, #main h4 {
    background: #ddd;
    background: linear-gradient(#f3f3f3,#f0f0f0,#eee,#e7e7e7,#d3d3d3);
    border-radius: 2pt;
    padding: 3.5pt 5pt;
    margin-top: 25pt;
}
#main label, #sidebar label {
    display: block;
    margin: 10pt 0;
    font-weight: 700;
}







|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    min-height: 700pt;
}

#main h2, #main h3, #main h4 {
    background: #ddd;
    background: linear-gradient(#f3f3f3,#f0f0f0,#eee,#e7e7e7,#d3d3d3);
    border-radius: 2pt;
    padding: 3.5pt 5pt 1.5pt 5pt;
    margin-top: 25pt;
}
#main label, #sidebar label {
    display: block;
    margin: 10pt 0;
    font-weight: 700;
}
294
295
296
297
298
299
300

301
302
303
304
305
306
307
#main .project .links a[href=""] {
    opacity: 0.15;
}
#main .project .published_date {
    font-weight: 200;
    font-size: 65%;
    color: #777;

}
#main .project img.preview {
    padding: 3px;
    border: 1px solid #eee;
    box-shadow: 2px 2px 7px 0px #ccc;
    margin: 3pt;
}







>







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#main .project .links a[href=""] {
    opacity: 0.15;
}
#main .project .published_date {
    font-weight: 200;
    font-size: 65%;
    color: #777;
    position: relative; top: -3.5pt;
}
#main .project img.preview {
    padding: 3px;
    border: 1px solid #eee;
    box-shadow: 2px 2px 7px 0px #ccc;
    margin: 3pt;
}
562
563
564
565
566
567
568




















































569
570
571
572
573
574
575
#trove_tags .optgroup[data-tag='operating-system']   { background: #ffe5e0; }
#trove_tags .optgroup[data-tag='operating-system'] * { background: #fce9e7; }
#trove_tags .optgroup[data-tag='audience']   { background: #e7f7ec; }
#trove_tags .optgroup[data-tag='audience'] * { background: #f0fff3; }
























































/**
 * Page footer
 *
 */
#spotlight {
    margin-top: 50pt;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
#trove_tags .optgroup[data-tag='operating-system']   { background: #ffe5e0; }
#trove_tags .optgroup[data-tag='operating-system'] * { background: #fce9e7; }
#trove_tags .optgroup[data-tag='audience']   { background: #e7f7ec; }
#trove_tags .optgroup[data-tag='audience'] * { background: #f0fff3; }




/**
 * Specific pages
 *
 */
table.rc {
   width: 100%;
   margin-top: 5pt;
}
.rc th {
   background: #ddd;
   font-weight: 500;
   padding: 3pt;
   text-align: left;
   border-radius: 5pt 5pt 0 0;
   box-shadow: 0px -2px 3px 1px #eee;
}
.rc td {
   background: #f7f9fc;
}
.rc th a {
   color: #22c;
}
.rc th:first-child {
   font-weight: 600;
}
.rc th:first-child,
.rc td:first-child {
   width: 15%;
}
.rc ins {
   color: #151;
   text-decoration: none;
   border-bottom: 1px dashed green;
   background: #efe;
}
.rc del {
   color: #521;
   background: #fee;
}
.rc .funcs {
   float: right;
}
.rc .funcs a {
   font-size: 60%;
   color: #99b;
   background: #e3e3e3;
   border: 1px solid #eee;
   border-radius: 3pt;
   padding: 1pt 3pt;
}


/**
 * Page footer
 *
 */
#spotlight {
    margin-top: 50pt;

Changes to index.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/**
 * api: php
 * title: Freshcode.club
 * description: FLOSS software release tracking website
 * version: 0.5.6
 * author: mario
 * license: AGPL
 * 
 * Implements a freshmeat/freecode-like directory for open source
 * release publishing / tracking.
 *
 */





|







1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/**
 * api: php
 * title: Freshcode.club
 * description: FLOSS software release tracking website
 * version: 0.5.9
 * author: mario
 * license: AGPL
 * 
 * Implements a freshmeat/freecode-like directory for open source
 * release publishing / tracking.
 *
 */
22
23
24
25
26
27
28

29

30
31
32
33
34
35
36

    case "index":
    case "projects":
    case "feed":
    case "forum":
    case "links":
    case "tags":

    case "search":

    case "drchangelog":
    case "login":
        include("page_$page.php");
        break;

    case "flag":
    case "submit":







>

>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

    case "index":
    case "projects":
    case "feed":
    case "forum":
    case "links":
    case "tags":
    case "names":
    case "search":
    case "rc":
    case "drchangelog":
    case "login":
        include("page_$page.php");
        break;

    case "flag":
    case "submit":

Added page_rc.php.



































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<?php
/**
 * type: page
 * title: Recent Changes
 * description: Provides a revision diff
 * version: 0.1
 *
 * Show differences between incremental revisions.
 * (To detect sneak spam while we're not requiring OpenID logons.)
 *
 */


// page header
include("template/header.php");
?><section id=main><?php


/**
 * Fields to inspect/diff.
 * Using different sets depending on publicness.
 *
 */
if (TRUE) {  // Public
    $fields = "name,t_changed,title,version,t_published,license,tags,state,scope,homepage,download,urls,description,changes,submitter";
}
if ($_SESSION["openid"]) {  // For logged in users
    $fields .= ",autoupdate_module,autoupdate_url,autoupdate_regex";
}
if (in_array($_SESSION["openid"], $moderator_ids)) {   // Reveal control/privacy-related fields only to moderators
    $fields .= ",submitter_image,submitter_openid,lock,hidden,deleted";
}


/**
 * Prepare SQL field aliases
 * (because sqlite-pdo driver doesn't support it)
 *
 *   description โ†’  crnt.description AS crnt_description
 *   description โ†’  prev.description AS prev_description
 *
 */
$crnt_fields_alias = preg_replace("/\w+/", "crnt.$0 AS crnt_$0", $fields);
$prev_fields_alias = preg_replace("/\w+/", "prev.$0 AS prev_$0", $fields);
$prev_fields_empty = preg_replace("/\w+/", "   NULL AS prev_$0", $fields);

// Also turn CSV list into array
$fields = array_diff(str_getcsv($fields), array("t_changed"));



/**
 * Retrieve two consecutive revisions each.
 *
 *
 */
$rc = db("

    SELECT $crnt_fields_alias, $prev_fields_alias,
           MAX(prev.t_changed)
      FROM release crnt
 LEFT JOIN release prev
        ON crnt.name = prev.name
     WHERE prev.t_changed < crnt.t_changed
--           ( SELECT MAX(t_changed)
--               FROM release
--              WHERE name = crnt.name
--                AND t_changed < crnt.t_changed )
  GROUP BY crnt.name, crnt.t_changed
  ORDER BY crnt.t_changed DESC

");



/**
 * Iterate over all results to display differences
 *
 */
foreach ($rc as $entry) {

    #-- Prepare fields
    $name = $entry["crnt_name"];
    $date = strftime("%Y-%m-%d %H:%M:%S", $entry["crnt_t_changed"]);
    $time_diff =  $entry["crnt_t_changed"] - $entry["prev_t_changed"];

    #-- Table
    print "\n\n<table class=rc><tr><th><a href=/projects/$name>$name</a></th><th>$date <small>ยค$time_diff</small> <span class=funcs><a href=/submit/$name>edit</a> <a href=/admin/$name>admin</a></span></th></tr>\n";
    foreach ($fields as $fn ) {

        // Diff only if there are differences, obviously
        if ($entry["prev_$fn"] !== $entry["crnt_$fn"]) {
        
            $diff = htmlDiff($entry["prev_$fn"], $entry["crnt_$fn"]);
            print "<tr><td>$fn</td><td class=trimmed>$diff</td></tr>\n";
        }
    }
    print "</table>\n";
}


// page footer
include("template/bottom.php");


?><?php
/*
    Paul's Simple Diff Algorithm v 0.1
    (C) Paul Butler 2007 <http://www.paulbutler.org/>
    May be used and distributed under the zlib/libpng license.
    
    This code is intended for learning purposes; it was written with short
    code taking priority over performance. It could be used in a practical
    application, but there are a few ways it could be optimized.
    
    Given two arrays, the function diff will return an array of the changes.
    I won't describe the format of the array, but it will be obvious
    if you use print_r() on the result of a diff on some test data.
    
    htmlDiff is a wrapper for the diff command, it takes two strings and
    returns the differences in HTML. The tags used are <ins> and <del>,
    which can easily be styled with CSS.  
*/

function diff($old, $new){
    $matrix = array();
    $maxlen = 0;
    foreach($old as $oindex => $ovalue){
        $nkeys = array_keys($new, $ovalue);
        foreach($nkeys as $nindex){
            $matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ?
                $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
            if($matrix[$oindex][$nindex] > $maxlen){
                $maxlen = $matrix[$oindex][$nindex];
                $omax = $oindex + 1 - $maxlen;
                $nmax = $nindex + 1 - $maxlen;
            }
        }   
    }
    if($maxlen == 0) return array(array('d'=>$old, 'i'=>$new));
    return array_merge(
        diff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)),
        array_slice($new, $nmax, $maxlen),
        diff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen)));
}

function htmlDiff($old, $new){
    $ret = '';
    $diff = diff(preg_split("/[\s]+/", $old), preg_split("/[\s]+/", $new));
    foreach($diff as $k){
        if(is_array($k))
            $ret .=
                (!empty($k['d']) ? "<del>" . input::html(implode(' ',$k['d'])) . "</del> " : '').
                (!empty($k['i']) ? "<ins>" . input::html(implode(' ',$k['i'])) . "</ins> " : '');
        else $ret .= $k . ' ';
    }
    return $ret;
}


?>

Changes to template/header.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48


49
50
51
52
53
54
55
<?php
/**
 * api: freshcode
 * type: template
 * title: HTML page header
 * description: Starts <html> and <head>, outputs top bar / menus etc.
 * version: 0.5.6
 *
 * Optionally injects a `$header_add` list, or allows to override the
 * page $title.
 *
 */
?>
<!DOCTYPE html>
<html>
<head> 
    <title><?= isset($title) ? $title : "freshcode.club" ?></title>
    <meta name=version content=0.5.5>
    <meta charset=UTF-8>
    <link rel=stylesheet href="/freshcode.css?0.6.2.1">
    <link rel="shortcut icon" href="/img/changes.png">
    <base href="//<?= HTTP_HOST ?>/">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <!--[if lt IE 9]><script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script><![endif]-->
    <script src="/gimmicks.js"></script>
    <?php if (isset($header_add)) { print $header_add . "\n"; } ?>
</head>
<body>

<nav id=topbar>
Open source community software release tracking.
<?= is_int(strpos(HTTP_HOST, ".")) ? '<small style="color:#9c7" class=version>[0.5.6 alpha]</small>' : '<b style="color:#c54">[local dev]</b>'; ?>
<span style=float:right>
<a href="//freshmeat.club/">freshmeat.club</a> |
<a href="//freecode.club/">freecode.club</a> |
<b><a href="//freshcode.club/">freshcode.club</a></b>
</span>
</nav>

<footer id=logo>
<a href="/" title="freshcode.club"><img src="img/logo.png" width=200 height=110 alt=freshcode border=0></a>
<div class=empty-box>&nbsp;</div>
</footer>

<nav id=tools>
   <a href="/">Home</a>
   <a href="/submit" class=submit>Submit</a>

   <a href="/tags">Browse Projects by Tag</a>


   <form id=search_q style="display:inline" action=search><input name=q size=5><a href="/search">Search</a></form>
   <a href="//fossil.include-once.org/freshcode/wiki/About">About</a>
   <a href="/links">Links</a>
   <a href="//www.opensourcestore.org/">Forum</a>
</nav>








|










|

|










|
|















>
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
/**
 * api: freshcode
 * type: template
 * title: HTML page header
 * description: Starts <html> and <head>, outputs top bar / menus etc.
 * version: 0.5.9
 *
 * Optionally injects a `$header_add` list, or allows to override the
 * page $title.
 *
 */
?>
<!DOCTYPE html>
<html>
<head> 
    <title><?= isset($title) ? $title : "freshcode.club" ?></title>
    <meta name=version content=0.5.9>
    <meta charset=UTF-8>
    <link rel=stylesheet href="/freshcode.css?0.6.2.9">
    <link rel="shortcut icon" href="/img/changes.png">
    <base href="//<?= HTTP_HOST ?>/">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <!--[if lt IE 9]><script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script><![endif]-->
    <script src="/gimmicks.js"></script>
    <?php if (isset($header_add)) { print $header_add . "\n"; } ?>
</head>
<body>

<nav id=topbar>
Open source software release tracking.
<?= is_int(strpos(HTTP_HOST, ".")) ? '<small style="color:#9c7" class=version>[0.5.9 alpha]</small>' : '<b style="color:#c54">[local dev]</b>'; ?>
<span style=float:right>
<a href="//freshmeat.club/">freshmeat.club</a> |
<a href="//freecode.club/">freecode.club</a> |
<b><a href="//freshcode.club/">freshcode.club</a></b>
</span>
</nav>

<footer id=logo>
<a href="/" title="freshcode.club"><img src="img/logo.png" width=200 height=110 alt=freshcode border=0></a>
<div class=empty-box>&nbsp;</div>
</footer>

<nav id=tools>
   <a href="/">Home</a>
   <a href="/submit" class=submit>Submit</a>
   <span class=submenu>
      <a href="/name">Browse Projects</a>
      <a href="/tags" style="left:-5pt;">by Tag</a>
   </span>
   <form id=search_q style="display:inline" action=search><input name=q size=5><a href="/search">Search</a></form>
   <a href="//fossil.include-once.org/freshcode/wiki/About">About</a>
   <a href="/links">Links</a>
   <a href="//www.opensourcestore.org/">Forum</a>
</nav>