update gitignore, add assets and files
10
.gitignore
vendored
|
|
@ -1,11 +1 @@
|
|||
.bundle
|
||||
_blog
|
||||
public/js/*.js
|
||||
public/css/*.css
|
||||
discussd/discuss.dirty
|
||||
public/blog
|
||||
public/proj
|
||||
node_modules
|
||||
public/s42/.htaccess
|
||||
public/images/blog
|
||||
public/f
|
||||
|
|
|
|||
179
public/css/blog.css
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
body { margin: 0
|
||||
; padding: 0
|
||||
}
|
||||
|
||||
h1 { margin: 0
|
||||
; padding: 0.2em
|
||||
; color: #9ab
|
||||
}
|
||||
|
||||
.center { text-align: center
|
||||
; font-size: 1.2em
|
||||
}
|
||||
|
||||
.hidden { display: none }
|
||||
|
||||
#index { width: 80%
|
||||
; min-width: 300px
|
||||
; max-width: 800px
|
||||
; border: solid 1px #999
|
||||
; -moz-border-radius: 10px
|
||||
; -webkit-border-radius: 10px
|
||||
; border-radius: 10px
|
||||
; background-color: #eee
|
||||
; margin: 1em auto
|
||||
; padding: 1em
|
||||
; font-size: 1.2em
|
||||
; line-height: 1.5em
|
||||
; list-style-type: none
|
||||
}
|
||||
|
||||
.date { float: right }
|
||||
|
||||
#article,
|
||||
article { width: 80%
|
||||
; min-width: 400px
|
||||
; max-width: 800px
|
||||
; margin: 0.6em auto
|
||||
; font-size: 1.2em
|
||||
; line-height: 1.4em
|
||||
; color: #222
|
||||
}
|
||||
|
||||
#article h1,
|
||||
article h1 { text-align: left
|
||||
; font-size: 2em
|
||||
; line-height: 1.2em
|
||||
; font-weight: normal
|
||||
; color: #222
|
||||
; margin: 0
|
||||
; padding-left: 0
|
||||
}
|
||||
|
||||
#article h1 a,
|
||||
article h1 a { color: #222
|
||||
; text-decoration: underline
|
||||
; border-bottom: none
|
||||
; text-shadow: #ccc 1px 1px 5px
|
||||
; -webkit-transition: text-shadow 0.4s ease-in
|
||||
}
|
||||
|
||||
#article h1 a:hover,
|
||||
article h1 a:hover { text-shadow: 1px 1px 6px #ffc
|
||||
; color: #000
|
||||
}
|
||||
|
||||
#article h2,
|
||||
article h2 { font-size: 1.8em
|
||||
; font-weight: normal
|
||||
; text-align: left
|
||||
; margin: 1em 0
|
||||
; padding: 0
|
||||
; color: #222
|
||||
}
|
||||
|
||||
#article h3,
|
||||
article h3 { font-size: 1.6em
|
||||
; font-weight: normal
|
||||
}
|
||||
|
||||
.time,
|
||||
time { color: #444
|
||||
; font-size: 1.2em
|
||||
}
|
||||
|
||||
.permalink { font-size: 1em }
|
||||
|
||||
.gist { font-size: 0.8em }
|
||||
|
||||
/* show discussion */
|
||||
#sd-container { margin: 3em 0 }
|
||||
|
||||
input[type=submit],
|
||||
#sd { border: solid 1px #999
|
||||
; border-right-color: #333
|
||||
; border-bottom-color: #333
|
||||
; padding: 0.4em 1em
|
||||
; color: #444
|
||||
; background-color: #ececec
|
||||
; -moz-border-radius: 5px
|
||||
; -webkit-border-radius: 5px
|
||||
; border-radius: 5px
|
||||
; text-decoration: none
|
||||
; margin: 0 2px 2px 0
|
||||
}
|
||||
|
||||
input[type=submit]:active,
|
||||
#sd:active { margin: 2px 0 0 2px
|
||||
; color: #000
|
||||
; background-color: #ffc
|
||||
}
|
||||
|
||||
#comment-stuff { display: none
|
||||
; color: #efefef
|
||||
; margin: 0
|
||||
; padding: 2em 0
|
||||
}
|
||||
|
||||
#comments-spinner { text-align: center }
|
||||
|
||||
#comments { width: 70%
|
||||
; max-width: 600px
|
||||
; margin: 0 auto
|
||||
}
|
||||
|
||||
.comment { color: #555
|
||||
; border-top: solid 2px #ccc
|
||||
; padding-bottom: 2em
|
||||
; margin-bottom: 2em
|
||||
}
|
||||
|
||||
.comment big { font-size: 2em
|
||||
; font-family: Verdana, sans-serif
|
||||
}
|
||||
|
||||
#comment-form { width: 400px
|
||||
; margin: 2em auto 0
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
textarea { font-size: 1.4em
|
||||
; color: #333
|
||||
; width: 100%
|
||||
; padding: 0.2em
|
||||
; border: solid 1px #999
|
||||
; -moz-border-radius: 5px
|
||||
; -webkit-border-radius: 5px
|
||||
; border-radius: 5px
|
||||
; font-family: verdana, sans-serif
|
||||
}
|
||||
|
||||
input:focus[type=text],
|
||||
textarea:focus { border: solid 1px #333 }
|
||||
|
||||
textarea { height: 100px }
|
||||
|
||||
input[type=submit] { font-size: 1.1em
|
||||
; cursor: pointer
|
||||
}
|
||||
|
||||
pre { background-color: #eeeef3
|
||||
; margin: 0.5em 1em 1em
|
||||
; padding: 0.5em
|
||||
; border: dashed 1px #ccc
|
||||
}
|
||||
|
||||
footer { margin: 0 auto
|
||||
; padding: 0.2em 0
|
||||
; border-top: solid 1px #ddd
|
||||
; clear: both
|
||||
; width: 80%
|
||||
}
|
||||
|
||||
footer p { margin: 0.5em }
|
||||
|
||||
footer a { border-bottom: none
|
||||
; color: #25c
|
||||
; font-size: 1.2em
|
||||
; text-decoration: none
|
||||
}
|
||||
7
public/css/ie6.css
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
ul { behavior: none
|
||||
; padding-bottom: 25px
|
||||
}
|
||||
|
||||
img { behavior: url(../js/iepngfix.htc)
|
||||
; behavior: url(../../js/iepngfix.htc)
|
||||
}
|
||||
1
public/css/ie7.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
ul#projects li { list-style-type: none }
|
||||
140
public/css/mobile.css
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/* phones and iPad */
|
||||
|
||||
@media only screen and (orientation: portrait) and (min-device-width: 768px) and (max-device-width: 1024px),
|
||||
only screen and (min-device-width: 320px) and (max-device-width: 480px),
|
||||
only screen and (max-device-width: 800px)
|
||||
{
|
||||
ul.nav { padding: 0.5em
|
||||
; width: 60%
|
||||
; max-width: 600px
|
||||
}
|
||||
|
||||
ul.nav li { display: block
|
||||
; font-size: 1.5em
|
||||
; line-height: 1.8em
|
||||
}
|
||||
|
||||
ul.nav li:after { content: '' }
|
||||
}
|
||||
|
||||
/* phones */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 480px),
|
||||
handheld and (max-device-width: 800px)
|
||||
{
|
||||
/* common */
|
||||
|
||||
h1 { font-size: 2em
|
||||
; margin-top: 0.5em
|
||||
}
|
||||
h2 { font-size: 1.3em; line-height: 1.2em }
|
||||
|
||||
.navbar { font-size: 0.9em }
|
||||
.navbar { width: 32% }
|
||||
#breadcrumbs { margin-left: 5px }
|
||||
|
||||
#show-posts { margin-top: 1em
|
||||
; font-size: 0.8em
|
||||
}
|
||||
|
||||
#forkme { display: none }
|
||||
|
||||
ul.nav { width: 80% }
|
||||
|
||||
ul.nav li { font-size: 1.4em
|
||||
; line-height: 1.6em
|
||||
}
|
||||
|
||||
td { font-size: 1em
|
||||
; line-height: 1.1em
|
||||
}
|
||||
|
||||
img { max-width: 100% }
|
||||
|
||||
#index { width: 90%
|
||||
; min-width: 200px
|
||||
; margin: 0.3em auto 1em
|
||||
; padding: 0.5em
|
||||
; font-size: 1em
|
||||
}
|
||||
|
||||
#index li > span.date { display: block
|
||||
; float: none
|
||||
; color: #666
|
||||
; font-size: 0.8em
|
||||
}
|
||||
|
||||
#article h1,
|
||||
article h1 { font-size: 1.6em
|
||||
; line-height: 1.2em
|
||||
; margin-top: 0
|
||||
}
|
||||
|
||||
article h2 { font-size: 1.4em }
|
||||
|
||||
#article,
|
||||
article { min-width: 310px
|
||||
; margin: 0
|
||||
; padding: 0.6em 0.4em
|
||||
; font-size: 0.8em
|
||||
}
|
||||
|
||||
.time,
|
||||
time { font-size: 1.0em }
|
||||
|
||||
pre, .gist { font-size: 0.8em }
|
||||
|
||||
#comment-stuff { padding: 0
|
||||
; margin-top: 2em
|
||||
}
|
||||
|
||||
#comments { width: 100% }
|
||||
|
||||
#comment-form { width: 90%
|
||||
; margin: 0 auto
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
textarea { font-size: 1.2em
|
||||
; width: 95%
|
||||
}
|
||||
|
||||
input[type=submit] { font-size: 1em }
|
||||
|
||||
/* proj */
|
||||
#info { width: 70%
|
||||
; padding: 0 1em
|
||||
}
|
||||
|
||||
#info > div { clear: left
|
||||
; width: 100%
|
||||
; max-width: 100%
|
||||
; padding: 0.5em 0.2em 1em
|
||||
; border-left: none
|
||||
; font-size: 1em
|
||||
}
|
||||
|
||||
#stats { font-size: 1em; margin-bottom: 0.5em }
|
||||
|
||||
footer { margin: 0
|
||||
; padding: 0.5em 0
|
||||
; font-size: 1em
|
||||
; width: 100%
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* landscape */
|
||||
|
||||
@media only screen and (orientation: landscape) and (min-device-width: 768px) and (max-device-width: 1024px),
|
||||
only screen and (orientation: landscape) and (min-device-width: 320px) and (max-device-width: 480px),
|
||||
handheld and (orientation: landscape) and (max-device-width: 800px)
|
||||
{
|
||||
body { font-size: 0.8em }
|
||||
}
|
||||
|
||||
|
||||
/* iPad portrait */
|
||||
@media only screen and (orientation: portrait) and (min-device-width: 768px) and (max-device-width: 1024px)
|
||||
{
|
||||
article > header > h1 { font-size: 1.8em }
|
||||
}
|
||||
51
public/css/projects.css
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
td { font-size: 1.5em
|
||||
; line-height: 1.6em
|
||||
}
|
||||
|
||||
td:nth-child(2) { padding: 0 10px }
|
||||
|
||||
.highlight { font-size: 1.2em }
|
||||
|
||||
#stats a { text-decoration: none }
|
||||
|
||||
#info { text-align: center
|
||||
; margin: 1em auto
|
||||
; padding: 1em
|
||||
; border: solid 1px #ccc
|
||||
; width: 90%
|
||||
; max-width: 950px
|
||||
; background-color: #fff
|
||||
; -moz-border-radius: 20px
|
||||
; -webkit-border-radius: 20px
|
||||
; border-radius: 20px
|
||||
; behavior: url(../js/border-radius.htc)
|
||||
; behavior: url(../../js/border-radius.htc)
|
||||
}
|
||||
|
||||
h4 { margin: 0.5em 0 0.7em }
|
||||
|
||||
#info > div { text-align: center
|
||||
; font-size: 1.3em
|
||||
; width: 31%
|
||||
; max-width: 400px
|
||||
; float: left
|
||||
; display: inline
|
||||
; padding: 0.5em 0.2em
|
||||
; border-left: dashed 1px #aaa
|
||||
}
|
||||
|
||||
#info > div:first-child { border-left: none }
|
||||
|
||||
#info ul { list-style-type: none
|
||||
; text-align: center
|
||||
; padding: 0
|
||||
; margin: 0
|
||||
}
|
||||
|
||||
#info li { padding: 0.2em 0
|
||||
; margin: 0
|
||||
}
|
||||
|
||||
#info > br.clear { clear: both }
|
||||
|
||||
#contributors-box a { line-height: 1.8em }
|
||||
92
public/css/style.css
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
TODO: include mobile.css here, just one set of styles
|
||||
|
||||
body { background-color: #f7f7f7
|
||||
; color: #222
|
||||
; font-family: 'Helvetica Neue', Verdana, sans-serif
|
||||
}
|
||||
|
||||
h1 { text-align: center
|
||||
; font-size: 2em
|
||||
; font-weight: normal
|
||||
; margin: 0.8em 0 0.4em
|
||||
; padding: 0
|
||||
}
|
||||
|
||||
h2 { text-align: center
|
||||
; font-size: 1.7em
|
||||
; line-height: 1.1em
|
||||
; font-weight: normal
|
||||
; margin: 0.2em 0 1em
|
||||
; padding: 0
|
||||
}
|
||||
|
||||
a { color: #0E539C }
|
||||
|
||||
a.img { border: none }
|
||||
|
||||
.navbar { display: inline-block
|
||||
; width: 33%
|
||||
; font-size: 1.5em
|
||||
; line-height: 1.8em
|
||||
; margin: 0
|
||||
; padding: 0
|
||||
}
|
||||
|
||||
.navbar a { text-shadow: none }
|
||||
|
||||
#breadcrumbs a { color: #222 }
|
||||
#title { text-align: center }
|
||||
#archive { text-align: right }
|
||||
|
||||
#forkme { position: absolute
|
||||
; top: 0
|
||||
; right: 0
|
||||
; border: none
|
||||
}
|
||||
|
||||
ul.nav { text-align: center
|
||||
; max-width: 400px
|
||||
; margin: 0 auto
|
||||
; padding: 1em
|
||||
; border: solid 1px #ccc
|
||||
; background-color: #fff
|
||||
; -moz-border-radius: 20px
|
||||
; -webkit-border-radius: 20px
|
||||
; border-radius: 20px
|
||||
; behavior: url(js/border-radius.htc)
|
||||
; behavior: url(../js/border-radius.htc)
|
||||
}
|
||||
|
||||
ul.nav li { display: block
|
||||
; font-size: 1.6em
|
||||
; line-height: 1.8em
|
||||
; margin: 0
|
||||
; padding: 0
|
||||
}
|
||||
|
||||
ul.nav li a { padding: 5px
|
||||
; text-decoration: none
|
||||
; border-bottom: solid 1px #fff
|
||||
; text-shadow: #ccc 2px 2px 3px
|
||||
}
|
||||
ul.nav li a:visited { color: #227 }
|
||||
|
||||
ul.nav li a:hover,
|
||||
ul.nav li a:active { text-shadow: #cca 2px 2px 3px
|
||||
; border-bottom: solid 1px #aaa
|
||||
}
|
||||
|
||||
ul.nav li a:active { text-shadow: none }
|
||||
|
||||
footer { text-align: center
|
||||
; font-size: 1.2em
|
||||
; margin: 1em
|
||||
}
|
||||
|
||||
footer a { border-bottom: none }
|
||||
|
||||
#promote-js { margin-top: 3em
|
||||
; text-align: center
|
||||
}
|
||||
|
||||
#promote-js img { border: none }
|
||||
77
public/css/typocode.css
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* Syntax highlighting */
|
||||
.typocode_ruby .normal {}
|
||||
.typocode_ruby .comment { color: #005; font-style: italic; }
|
||||
.typocode_ruby .keyword { color: #A00; font-weight: bold; }
|
||||
.typocode_ruby .method { color: #077; }
|
||||
.typocode_ruby .class { color: #074; }
|
||||
.typocode_ruby .module { color: #050; }
|
||||
.typocode_ruby .punct { color: #447; font-weight: bold; }
|
||||
.typocode_ruby .symbol { color: #099; }
|
||||
.typocode_ruby .string { color: #944; background: #FFE; }
|
||||
.typocode_ruby .char { color: #F07; }
|
||||
.typocode_ruby .ident { color: #004; }
|
||||
.typocode_ruby .constant { color: #07F; }
|
||||
.typocode_ruby .regex { color: #B66; background: #FEF; }
|
||||
.typocode_ruby .number { color: #F99; }
|
||||
.typocode_ruby .attribute { color: #7BB; }
|
||||
.typocode_ruby .global { color: #7FB; }
|
||||
.typocode_ruby .expr { color: #227; }
|
||||
.typocode_ruby .escape { color: #277; }
|
||||
.typocode_xml .normal {}
|
||||
.typocode_xml .namespace { color: #B66; font-weight: bold; }
|
||||
.typocode_xml .tag { color: #F88; }
|
||||
.typocode_xml .comment { color: #005; font-style: italic; }
|
||||
.typocode_xml .punct { color: #447; font-weight: bold; }
|
||||
.typocode_xml .string { color: #944; }
|
||||
.typocode_xml .number { color: #F99; }
|
||||
.typocode_xml .attribute { color: #BB7; }
|
||||
.typocode_yaml .normal {}
|
||||
.typocode_yaml .document { font-weight: bold; color: #07F; }
|
||||
.typocode_yaml .type { font-weight: bold; color: #05C; }
|
||||
.typocode_yaml .key { color: #F88; }
|
||||
.typocode_yaml .comment { color: #005; font-style: italic; }
|
||||
.typocode_yaml .punct { color: #447; font-weight: bold; }
|
||||
.typocode_yaml .string { color: #944; }
|
||||
.typocode_yaml .number { color: #F99; }
|
||||
.typocode_yaml .time { color: #F99; }
|
||||
.typocode_yaml .date { color: #F99; }
|
||||
.typocode_yaml .ref { color: #944; }
|
||||
.typocode_yaml .anchor { color: #944; }
|
||||
|
||||
.typocode {
|
||||
background-color:#eee;
|
||||
padding:2px;
|
||||
margin:5px;
|
||||
margin-left:1em;
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
||||
.typocode pre {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: monospace;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
|
||||
.typocode .lineno {
|
||||
text-align: right;
|
||||
/* color: #B00;*/
|
||||
font-family: monospace;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Andale Mono", "Lucida Typewriter", "Bitstream Vera Sans Mono", fixed-width, monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #555;
|
||||
border: 1px dashed #5189ea;
|
||||
margin-bottom: 30px;
|
||||
margin-top: -10px;
|
||||
padding: 5px;
|
||||
}
|
||||
BIN
public/f/Carmina Burana - O Fortuna.m4r
Normal file
BIN
public/f/Carmina Burana - O Fortuna.mp3
Normal file
BIN
public/f/IntelligentMigrationSnippets-0.1.dmg
Normal file
BIN
public/f/SJRailsBundle-0.2.dmg
Normal file
BIN
public/f/assert_snippets.zip
Normal file
260
public/f/cheat.el
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
;; cheat.el
|
||||
;; Time-stamp: <2007-08-22 10:00:04 sjs>
|
||||
;;
|
||||
;; Copyright (c) 2007 Sami Samhuri <sami.samhuri@gmail.com>
|
||||
;;
|
||||
;; See http://sami.samhuri.net/2007/08/10/cheat-from-emacs for updates.
|
||||
;;
|
||||
;; License
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or
|
||||
;; modify it under the terms of the GNU General Public License
|
||||
;; as published by the Free Software Foundation; either version 2
|
||||
;; of the License, or (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program; if not, write to the Free Software
|
||||
;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
;;
|
||||
;;
|
||||
;; Provide a handy interface to cheat.
|
||||
;; See http://cheat.errtheblog.com for details on cheat itself.
|
||||
;;
|
||||
;; sjs 2007.08.21
|
||||
;; * Cache the list of cheat sheets, update it once a day (configurable).
|
||||
;; * Strictly complete cheat sheet names.
|
||||
|
||||
(defvar *cheat-host* "cheat.errtheblog.com")
|
||||
(defvar *cheat-port* "80")
|
||||
(defvar *cheat-uri* (concat *cheat-host* ":" *cheat-port*))
|
||||
|
||||
(defvar *cheat-directory* "~/.cheat")
|
||||
(defvar *cheat-sheets-cache-file* (concat *cheat-directory* "/sheets"))
|
||||
|
||||
(defvar *cheat-last-sheet* nil
|
||||
"Name of the most recently viewed cheat sheet.")
|
||||
|
||||
(defvar *cheat-sheet-history* nil
|
||||
"List of the most recently viewed cheat sheets.")
|
||||
|
||||
(defconst +seconds-per-day+ 86400)
|
||||
|
||||
(defvar *cheat-cache-ttl* +seconds-per-day+
|
||||
"The minimum age of a stale cache file, in seconds.")
|
||||
|
||||
|
||||
;;; interactive functions
|
||||
|
||||
(defun cheat (name &optional silent)
|
||||
"Show the specified cheat sheet.
|
||||
|
||||
If SILENT is non-nil then do not print any output, but return it
|
||||
as a string instead."
|
||||
(interactive (list (cheat-read-sheet-name)))
|
||||
(if silent
|
||||
(cheat-command-silent name)
|
||||
(cheat-command name)))
|
||||
|
||||
(defun cheat-sheets ()
|
||||
"List all cheat sheets."
|
||||
(interactive)
|
||||
(cheat-command "sheets"))
|
||||
|
||||
(defun cheat-recent ()
|
||||
"Show recently added cheat sheets."
|
||||
(interactive)
|
||||
(cheat-command "recent"))
|
||||
|
||||
(defun cheat-clear-cache ()
|
||||
"Clear the local cheat cache, located in ~/.cheat."
|
||||
(interactive)
|
||||
(cheat-command "--clear-cache")
|
||||
(make-directory *cheat-directory*))
|
||||
|
||||
(defun cheat-versions (name)
|
||||
"Version history of the specified cheat sheet."
|
||||
(interactive (list (cheat-read-sheet-name)))
|
||||
(cheat-command name "--versions"))
|
||||
|
||||
(defun cheat-diff (name version)
|
||||
"Show the diff between the given version and the current version of the named cheat.
|
||||
If VERSION is of the form m:n then show the diff between versions m and n."
|
||||
(interactive (list (cheat-read-sheet-name)
|
||||
(read-string "Cheat version(s): ")))
|
||||
(cheat-command name "--diff" version))
|
||||
|
||||
(defun cheat-add-current-buffer (name)
|
||||
"Add a new cheat with the specified name and the current buffer as the body."
|
||||
(interactive "sCheat name: \n")
|
||||
(post-cheat name (buffer-string) t)
|
||||
(if (interactive-p)
|
||||
(print (concat "Cheat added (" name ")"))))
|
||||
|
||||
(defun cheat-edit (name)
|
||||
"Fetch the named cheat and open a buffer containing its body.
|
||||
The cheat can be saved with `cheat-save-current-buffer'."
|
||||
(interactive (list (cheat-read-sheet-name)))
|
||||
(cheat-clear-cache name) ; make sure we're working with the latest version
|
||||
(switch-to-buffer (get-buffer-create (cheat->buffer name)))
|
||||
(insert (cheat-body name))
|
||||
(if (interactive-p)
|
||||
(print "Run `cheat-save-current-buffer' when you're done editing.")))
|
||||
|
||||
(defun cheat-save-current-buffer ()
|
||||
"Save the current buffer using the buffer name for the title and the contents as the body."
|
||||
(interactive)
|
||||
(let ((name (buffer->cheat (buffer-name (current-buffer)))))
|
||||
(post-cheat name (buffer-string))
|
||||
;; TODO check for errors and kill the buffer on success
|
||||
(if (interactive-p)
|
||||
(print (concat "Cheat saved (" name ")")))
|
||||
(cheat-clear-cache name)
|
||||
(cheat name)))
|
||||
|
||||
|
||||
;;; helpers
|
||||
|
||||
;; this is from rails-lib.el in the emacs-rails package
|
||||
(defun string-join (separator strings)
|
||||
"Join all STRINGS using SEPARATOR."
|
||||
(mapconcat 'identity strings separator))
|
||||
|
||||
(defun blank (thing)
|
||||
"Return T if THING is nil or an empty string, otherwise nil."
|
||||
(or (null thing)
|
||||
(and (stringp thing)
|
||||
(= 0 (length thing)))))
|
||||
|
||||
(defun cheat-command (&rest rest)
|
||||
"Run the cheat command with the given arguments, display the output."
|
||||
(interactive "sArguments for cheat: \n")
|
||||
(shell-command (concat "cheat " (string-join " " rest))))
|
||||
|
||||
(defun cheat-command-to-string (&rest rest)
|
||||
"Run the cheat command with the given arguments and return the output as a string. Display nothing."
|
||||
(shell-command-to-string (concat "cheat " (string-join " " rest))))
|
||||
|
||||
(defalias 'cheat-command-silent 'cheat-command-to-string)
|
||||
|
||||
(defun cheat-read-sheet-name (&optional prompt)
|
||||
"Get the name of an existing cheat sheet, prompting with completion and history.
|
||||
|
||||
The name of the sheet read is stored in *cheat-last-sheet* unless it was blank."
|
||||
(let* ((default (when (blank prompt) *cheat-last-sheet*))
|
||||
(prompt (or prompt
|
||||
(if (not (blank default))
|
||||
(concat "Cheat name (default: " default "): ")
|
||||
"Cheat name: ")))
|
||||
(name (completing-read prompt
|
||||
(cheat-sheets-list t)
|
||||
nil
|
||||
t
|
||||
nil
|
||||
'*cheat-sheet-history*
|
||||
default)))
|
||||
(when (not (blank name))
|
||||
(setq *cheat-last-sheet* name))
|
||||
name))
|
||||
|
||||
(defun cheat-sheets-list (&optional fetch-if-missing-or-stale)
|
||||
"Get a list of all cheat sheets.
|
||||
|
||||
Return the cached list in *cheat-sheets-cache-file* if it's
|
||||
readable and `cheat-cache-stale-p' returns nil.
|
||||
|
||||
When there is no cache or a stale cache, and
|
||||
FETCH-IF-MISSING-OR-STALE is non-nil, cache the list and then
|
||||
return it.
|
||||
|
||||
Otherwise return nil."
|
||||
(cond ((and (file-readable-p *cheat-sheets-cache-file*)
|
||||
(not (cheat-cache-stale-p)))
|
||||
(save-excursion
|
||||
(let* ((buffer (find-file *cheat-sheets-cache-file*))
|
||||
(sheets (split-string (buffer-string))))
|
||||
(kill-buffer buffer)
|
||||
sheets)))
|
||||
(fetch-if-missing-or-stale
|
||||
(cheat-cache-list)
|
||||
(cheat-sheets-list))
|
||||
(t nil)))
|
||||
|
||||
(defun cheat-fetch-list ()
|
||||
"Fetch a fresh list of all cheat sheets."
|
||||
(nthcdr 3 (split-string (cheat-command-to-string "sheets"))))
|
||||
|
||||
(defun cheat-cache-list ()
|
||||
"Cache the list of cheat sheets in *cheat-sheets-cache-file*. Return the list."
|
||||
(when (not (file-exists-p *cheat-directory*))
|
||||
(make-directory *cheat-directory*))
|
||||
(save-excursion
|
||||
(let ((buffer (find-file *cheat-sheets-cache-file*))
|
||||
(sheets (cheat-fetch-list)))
|
||||
(insert (string-join "\n" sheets))
|
||||
(basic-save-buffer)
|
||||
(kill-buffer buffer)
|
||||
sheets)))
|
||||
|
||||
(defun cheat-cache-stale-p ()
|
||||
"Non-nil if the cache in *cheat-sheets-cache-file* is more than *cheat-cache-ttl* seconds old.q
|
||||
|
||||
If the cache file does not exist then it is considered stale.
|
||||
|
||||
Also see `cheat-cache-sheets'."
|
||||
(or (null (file-exists-p *cheat-sheets-cache-file*))
|
||||
(let* ((now (float-time (current-time)))
|
||||
(last-mod (float-time (sixth (file-attributes *cheat-sheets-cache-file*))))
|
||||
(age (- now last-mod)))
|
||||
(> age *cheat-cache-ttl*))))
|
||||
|
||||
(defun cheat-body (name)
|
||||
"Call out to Ruby to load the YAML and return just the body."
|
||||
(shell-command-to-string
|
||||
(concat "ruby -ryaml -e '"
|
||||
"puts YAML.load_file(File.expand_path(\"~/.cheat/"
|
||||
name ".yml\")).to_a[0][-1]'")))
|
||||
|
||||
(defun url-http-post (url args)
|
||||
"Send ARGS to URL as a POST request."
|
||||
(let ((url-request-method "POST")
|
||||
(url-request-extra-headers
|
||||
'(("Content-Type" . "application/x-www-form-urlencoded")))
|
||||
(url-request-data
|
||||
(concat (mapconcat (lambda (arg)
|
||||
(concat (url-hexify-string (car arg))
|
||||
"="
|
||||
(url-hexify-string (cdr arg))))
|
||||
args
|
||||
"&")
|
||||
"\r\n")))
|
||||
;; `kill-url-buffer' to discard the result
|
||||
;; `switch-to-url-buffer' to view the results (debugging).
|
||||
(url-retrieve url 'kill-url-buffer)))
|
||||
|
||||
(defun kill-url-buffer (status)
|
||||
"Kill the buffer returned by `url-retrieve'."
|
||||
(kill-buffer (current-buffer)))
|
||||
|
||||
(defun switch-to-url-buffer (status)
|
||||
"Switch to the buffer returned by `url-retreive'.
|
||||
The buffer contains the raw HTTP response sent by the server."
|
||||
(switch-to-buffer (current-buffer)))
|
||||
|
||||
(defun post-cheat (title body &optional new)
|
||||
(let ((uri (concat "http://" *cheat-uri* "/w/" (if new "" title))))
|
||||
(url-http-post uri `(("sheet_title" . ,title)
|
||||
("sheet_body" . ,body)
|
||||
("from_gem" . "1")))))
|
||||
|
||||
(defun buffer->cheat (name)
|
||||
(substring name 7 (- (length name) 1)))
|
||||
|
||||
(defun cheat->buffer (name)
|
||||
(concat "*cheat-" name "*"))
|
||||
|
||||
(provide 'cheat)
|
||||
BIN
public/f/download.png
Normal file
|
After Width: | Height: | Size: 139 B |
BIN
public/f/ember-structure.png
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
public/f/feed-icon-48x48.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
256
public/f/feed-icon32x32.png
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>samhuri.net</title>
|
||||
<style type='text/css'>
|
||||
body {
|
||||
background: #000;
|
||||
color: #ffc;
|
||||
}
|
||||
a, a:link {
|
||||
color: #ff6;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover { color: #ff0; }
|
||||
p { font-size: 72px; text-align: center; margin-top: 30%; }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- BEGIN WAYBACK TOOLBAR INSERT -->
|
||||
|
||||
<script type="text/javascript" src="http://staticweb.archive.org/js/disclaim-element.js" ></script>
|
||||
<script type="text/javascript" src="http://staticweb.archive.org/js/graph-calc.js" ></script>
|
||||
<script type="text/javascript" src="http://staticweb.archive.org/jflot/jquery.min.js" ></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var firstDate = 820454400000;
|
||||
var lastDate = 1325375999999;
|
||||
var wbPrefix = "http://web.archive.org/web/";
|
||||
var wbCurrentUrl = "http://samhuri.net/";
|
||||
|
||||
var curYear = -1;
|
||||
var curMonth = -1;
|
||||
var yearCount = 16;
|
||||
var firstYear = 1996;
|
||||
var imgWidth=400;
|
||||
var yearImgWidth = 25;
|
||||
var monthImgWidth = 2;
|
||||
var trackerVal = "none";
|
||||
var displayDay = "5";
|
||||
var displayMonth = "Dec";
|
||||
var displayYear = "2006";
|
||||
var prettyMonths = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
|
||||
|
||||
function showTrackers(val) {
|
||||
if(val == trackerVal) {
|
||||
return;
|
||||
}
|
||||
if(val == "inline") {
|
||||
document.getElementById("displayYearEl").style.color = "#ec008c";
|
||||
document.getElementById("displayMonthEl").style.color = "#ec008c";
|
||||
document.getElementById("displayDayEl").style.color = "#ec008c";
|
||||
} else {
|
||||
document.getElementById("displayYearEl").innerHTML = displayYear;
|
||||
document.getElementById("displayYearEl").style.color = "#ff0";
|
||||
document.getElementById("displayMonthEl").innerHTML = displayMonth;
|
||||
document.getElementById("displayMonthEl").style.color = "#ff0";
|
||||
document.getElementById("displayDayEl").innerHTML = displayDay;
|
||||
document.getElementById("displayDayEl").style.color = "#ff0";
|
||||
}
|
||||
document.getElementById("wbMouseTrackYearImg").style.display = val;
|
||||
document.getElementById("wbMouseTrackMonthImg").style.display = val;
|
||||
trackerVal = val;
|
||||
}
|
||||
function getElementX2(obj) {
|
||||
var thing = jQuery(obj);
|
||||
if((thing == undefined)
|
||||
|| (typeof thing == "undefined")
|
||||
|| (typeof thing.offset == "undefined")) {
|
||||
return getElementX(obj);
|
||||
}
|
||||
return Math.round(thing.offset().left);
|
||||
}
|
||||
function trackMouseMove(event,element) {
|
||||
|
||||
var eventX = getEventX(event);
|
||||
var elementX = getElementX2(element);
|
||||
var xOff = eventX - elementX;
|
||||
if(xOff < 0) {
|
||||
xOff = 0;
|
||||
} else if(xOff > imgWidth) {
|
||||
xOff = imgWidth;
|
||||
}
|
||||
var monthOff = xOff % yearImgWidth;
|
||||
|
||||
var year = Math.floor(xOff / yearImgWidth);
|
||||
var yearStart = year * yearImgWidth;
|
||||
var monthOfYear = Math.floor(monthOff / monthImgWidth);
|
||||
if(monthOfYear > 11) {
|
||||
monthOfYear = 11;
|
||||
}
|
||||
// 1 extra border pixel at the left edge of the year:
|
||||
var month = (year * 12) + monthOfYear;
|
||||
var day = 1;
|
||||
if(monthOff % 2 == 1) {
|
||||
day = 15;
|
||||
}
|
||||
var dateString =
|
||||
zeroPad(year + firstYear) +
|
||||
zeroPad(monthOfYear+1,2) +
|
||||
zeroPad(day,2) + "000000";
|
||||
|
||||
var monthString = prettyMonths[monthOfYear];
|
||||
document.getElementById("displayYearEl").innerHTML = year + 1996;
|
||||
document.getElementById("displayMonthEl").innerHTML = monthString;
|
||||
// looks too jarring when it changes..
|
||||
//document.getElementById("displayDayEl").innerHTML = zeroPad(day,2);
|
||||
|
||||
var url = wbPrefix + dateString + '/' + wbCurrentUrl;
|
||||
document.getElementById('wm-graph-anchor').href = url;
|
||||
|
||||
//document.getElementById("wmtbURL").value="evX("+eventX+") elX("+elementX+") xO("+xOff+") y("+year+") m("+month+") monthOff("+monthOff+") DS("+dateString+") Moy("+monthOfYear+") ms("+monthString+")";
|
||||
if(curYear != year) {
|
||||
var yrOff = year * yearImgWidth;
|
||||
document.getElementById("wbMouseTrackYearImg").style.left = yrOff + "px";
|
||||
curYear = year;
|
||||
}
|
||||
if(curMonth != month) {
|
||||
var mtOff = year + (month * monthImgWidth) + 1;
|
||||
document.getElementById("wbMouseTrackMonthImg").style.left = mtOff + "px";
|
||||
curMonth = month;
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<style type="text/css">body{margin-top:0!important;padding-top:0!important;min-width:800px!important;}#wm-ipp a:hover{text-decoration:underline!important;}</style>
|
||||
<div id="wm-ipp" style="display:none; position:relative;padding:0 5px;min-height:70px;min-width:800px; z-index:9000;">
|
||||
<div id="wm-ipp-inside" style="position:fixed;padding:0!important;margin:0!important;width:97%;min-width:780px;border:5px solid #000;border-top:none;background-image:url(http://staticweb.archive.org/images/toolbar/wm_tb_bk_trns.png);text-align:center;-moz-box-shadow:1px 1px 3px #333;-webkit-box-shadow:1px 1px 3px #333;box-shadow:1px 1px 3px #333;font-size:11px!important;font-family:'Lucida Grande','Arial',sans-serif!important;">
|
||||
<table style="border-collapse:collapse;margin:0;padding:0;width:100%;"><tbody><tr>
|
||||
<td style="padding:10px;vertical-align:top;min-width:110px;">
|
||||
<a href="http://wayback.archive.org/web/" title="Wayback Machine home page" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wayback-toolbar-logo.png" alt="Wayback Machine" width="110" height="39" border="0"/></a>
|
||||
</td>
|
||||
<td style="padding:0!important;text-align:center;vertical-align:top;width:100%;">
|
||||
|
||||
<table style="border-collapse:collapse;margin:0 auto;padding:0;width:570px;"><tbody><tr>
|
||||
<td style="padding:3px 0;" colspan="2">
|
||||
<form target="_top" method="get" action="http://wayback.archive.org/web/form-submit.jsp" name="wmtb" id="wmtb" style="margin:0!important;padding:0!important;"><input type="text" name="url" id="wmtbURL" value="http://samhuri.net/" style="width:400px;font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;" onfocus="javascript:this.focus();this.select();" /><input type="hidden" name="type" value="replay" /><input type="hidden" name="date" value="20061205055004" /><input type="submit" value="Go" style="font-size:11px;font-family:'Lucida Grande','Arial',sans-serif;margin-left:5px;" /><span id="wm_tb_options" style="display:block;"></span></form>
|
||||
</td>
|
||||
<td style="vertical-align:bottom;padding:5px 0 0 0!important;" rowspan="2">
|
||||
<table style="border-collapse:collapse;width:110px;color:#99a;font-family:'Helvetica','Lucida Grande','Arial',sans-serif;"><tbody>
|
||||
|
||||
<!-- NEXT/PREV MONTH NAV AND MONTH INDICATOR -->
|
||||
<tr style="width:110px;height:16px;font-size:10px!important;">
|
||||
<td style="padding-right:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
|
||||
|
||||
<a href="http://web.archive.org/web/20061004083901/http://samhuri.net/" style="text-decoration:none;color:#33f;font-weight:bold;background-color:transparent;border:none;" title="4 Oct 2006"><strong>OCT</strong></a>
|
||||
|
||||
</td>
|
||||
<td id="displayMonthEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight:bold;text-transform:uppercase;width:34px;height:15px;padding-top:1px;text-align:center;" title="You are here: 5:50:04 Dec 5, 2006">DEC</td>
|
||||
<td style="padding-left:9px;font-size:11px!important;font-weight:bold;text-transform:uppercase;white-space:nowrap;overflow:visible;" nowrap="nowrap">
|
||||
|
||||
Jan
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- NEXT/PREV CAPTURE NAV AND DAY OF MONTH INDICATOR -->
|
||||
<tr>
|
||||
<td style="padding-right:9px;white-space:nowrap;overflow:visible;text-align:right!important;vertical-align:middle!important;" nowrap="nowrap">
|
||||
|
||||
<a href="http://web.archive.org/web/20061004083901/http://samhuri.net/" title="8:39:01 Oct 4, 2006" style="background-color:transparent;border:none;"><img src="http://staticweb.archive.org/images/toolbar/wm_tb_prv_on.png" alt="Previous capture" width="14" height="16" border="0" /></a>
|
||||
|
||||
</td>
|
||||
<td id="displayDayEl" style="background:#000;color:#ff0;width:34px;height:24px;padding:2px 0 0 0;text-align:center;font-size:24px;font-weight: bold;" title="You are here: 5:50:04 Dec 5, 2006">5</td>
|
||||
<td style="padding-left:9px;white-space:nowrap;overflow:visible;text-align:left!important;vertical-align:middle!important;" nowrap="nowrap">
|
||||
|
||||
<img src="http://staticweb.archive.org/images/toolbar/wm_tb_nxt_off.png" alt="Next capture" width="14" height="16" border="0"/>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- NEXT/PREV YEAR NAV AND YEAR INDICATOR -->
|
||||
<tr style="width:110px;height:13px;font-size:9px!important;">
|
||||
<td style="padding-right:9px;font-size:11px!important;font-weight: bold;text-align:right;white-space:nowrap;overflow:visible;" nowrap="nowrap">
|
||||
|
||||
2005
|
||||
|
||||
</td>
|
||||
<td id="displayYearEl" style="background:#000;color:#ff0;font-size:11px!important;font-weight: bold;padding-top:1px;width:34px;height:13px;text-align:center;" title="You are here: 5:50:04 Dec 5, 2006">2006</td>
|
||||
<td style="padding-left:9px;font-size:11px!important;font-weight: bold;white-space:nowrap;overflow:visible;" nowrap="nowrap">
|
||||
|
||||
2007
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align:middle;padding:0!important;">
|
||||
<a href="http://wayback.archive.org/web/20061205055004*/http://samhuri.net/" style="color:#33f;font-size:11px;font-weight:bold;background-color:transparent;border:none;" title="See a list of every capture for this URL"><strong>7 captures</strong></a>
|
||||
<div style="margin:0!important;padding:0!important;color:#666;font-size:9px;padding-top:2px!important;white-space:nowrap;" title="Timespan for captures of this URL">2 Apr 06 - 5 Dec 06</div>
|
||||
</td>
|
||||
<td style="padding:0!important;">
|
||||
<a style="position:relative; white-space:nowrap; width:400px;height:27px;" href="" id="wm-graph-anchor">
|
||||
<div id="wm-ipp-sparkline" style="position:relative; white-space:nowrap; width:400px;height:27px;background-color:#fff;cursor:pointer;border-right:1px solid #ccc;" title="Explore captures for this URL">
|
||||
<img id="sparklineImgId" style="position:absolute; z-index:9012; top:0px; left:0px;"
|
||||
onmouseover="showTrackers('inline');"
|
||||
onmouseout="showTrackers('none');"
|
||||
onmousemove="trackMouseMove(event,this)"
|
||||
alt="sparklines"
|
||||
width="400"
|
||||
height="27"
|
||||
border="0"
|
||||
src="http://wayback.archive.org/jsp/graph.jsp?graphdata=400_27_1996:-1:000000000000_1997:-1:000000000000_1998:-1:000000000000_1999:-1:000000000000_2000:-1:000000000000_2001:-1:000000000000_2002:-1:000000000000_2003:-1:000000000000_2004:-1:000000000000_2005:-1:000000000000_2006:11:000101030101_2007:-1:000000000000_2008:-1:000000000000_2009:-1:000000000000_2010:-1:000000000000_2011:-1:000000000000"></img>
|
||||
<img id="wbMouseTrackYearImg"
|
||||
style="display:none; position:absolute; z-index:9010;"
|
||||
width="25"
|
||||
height="27"
|
||||
border="0"
|
||||
src="http://staticweb.archive.org/images/toolbar/transp-yellow-pixel.png"></img>
|
||||
<img id="wbMouseTrackMonthImg"
|
||||
style="display:none; position:absolute; z-index:9011; "
|
||||
width="2"
|
||||
height="27"
|
||||
border="0"
|
||||
src="http://staticweb.archive.org/images/toolbar/transp-red-pixel.png"></img>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</td>
|
||||
</tr></tbody></table>
|
||||
</td>
|
||||
<td style="text-align:right;padding:5px;width:65px;font-size:11px!important;">
|
||||
<a href="javascript:;" onclick="document.getElementById('wm-ipp').style.display='none';" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_close.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;margin-bottom:23px;background-color:transparent;border:none;" title="Close the toolbar">Close</a>
|
||||
<a href="http://faq.web.archive.org/" style="display:block;padding-right:18px;background:url(http://staticweb.archive.org/images/toolbar/wm_tb_help.png) no-repeat 100% 0;color:#33f;font-family:'Lucida Grande','Arial',sans-serif;background-color:transparent;border:none;" title="Get some help using the Wayback Machine">Help</a>
|
||||
</td>
|
||||
</tr></tbody></table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var wmDisclaimBanner = document.getElementById("wm-ipp");
|
||||
if(wmDisclaimBanner != null) {
|
||||
disclaimElement(wmDisclaimBanner);
|
||||
}
|
||||
</script>
|
||||
<!-- END WAYBACK TOOLBAR INSERT -->
|
||||
|
||||
<p>samhuri.net</a>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
FILE ARCHIVED ON 5:50:04 Dec 5, 2006 AND RETRIEVED FROM THE
|
||||
INTERNET ARCHIVE ON 2:38:29 Aug 21, 2011.
|
||||
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
|
||||
|
||||
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
|
||||
SECTION 108(a)(3)).
|
||||
-->
|
||||
35
public/f/german_keys.txt
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
DVORAK
|
||||
------
|
||||
§1234567890[]
|
||||
±!@#$%^&*(){}
|
||||
|
||||
',.pyfgcrl/=
|
||||
"<>PYFGCRL?+
|
||||
|
||||
aoeuidhtns-\
|
||||
AOEUIDHTNS_|
|
||||
|
||||
`;qjkxbmwvz
|
||||
~:QJKXBMWVZ
|
||||
|
||||
|
||||
QWERTY
|
||||
------
|
||||
§12344567890-=
|
||||
±!@#$%^&*()_+
|
||||
|
||||
qwertyuiop[]
|
||||
QWERTYUIOP{}
|
||||
|
||||
asdfghjkl;'\
|
||||
ASDFGHJKL:"|
|
||||
|
||||
`zxcvbnm,./
|
||||
~ZXCVBNM<>?
|
||||
|
||||
|
||||
QWERTZ (German)
|
||||
---------------
|
||||
^1234567890ß´
|
||||
°!"§$%&/()=?`
|
||||
|
||||
14
public/f/gtkpod-aac-fix.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
mkdir /tmp/gtkpod-fix
|
||||
cd /tmp/gtkpod-fix
|
||||
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmp4v2-0_1.5.0.1-0.3_amd64.deb
|
||||
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmp4v2-dev_1.5.0.1-0.3_amd64.deb
|
||||
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmpeg4ip-0_1.5.0.1-0.3_amd64.deb
|
||||
wget http://ftp.uni-kl.de/debian-multimedia/pool/main/libm/libmpeg4ip/libmpeg4ip-dev_1.5.0.1-0.3_amd64.deb
|
||||
for f in *.deb; do sudo gdebi -n "$f"; done
|
||||
svn co https://gtkpod.svn.sourceforge.net/svnroot/gtkpod/gtkpod/trunk gtkpod
|
||||
cd gtkpod
|
||||
./autogen.sh --with-mp4v2 && make && sudo make install
|
||||
cd
|
||||
rm -rf /tmp/gtkpod-fix
|
||||
BIN
public/f/ims-demo.mov
Normal file
438
public/f/island.css
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
/* Island screen styles */
|
||||
|
||||
body {
|
||||
font: 1em/1.15em "Hoefler Text", Georgia, "Adobe Garamond Pro", Palatino, "Times New Roman", serif;
|
||||
color: #eee;
|
||||
background: #000;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#leftcolumn {
|
||||
width: 23%;
|
||||
float: right;
|
||||
margin: 0 10px 0 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#header {
|
||||
/* text-align: center;*/
|
||||
}
|
||||
|
||||
#content {
|
||||
/* padding-top: 50px;*/
|
||||
width: 72%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#main {
|
||||
}
|
||||
|
||||
#search {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
}
|
||||
|
||||
#footer {
|
||||
text-align: center;
|
||||
/* background: #333;*/
|
||||
border-top: 1px solid #666;
|
||||
padding-bottom: 5px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#footer a { border: none; }
|
||||
#footer img { border: none; }
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| LINKS |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
a {
|
||||
color: #5189ea;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #3179ca;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background: #ffa;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| UTILITY |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
form, div { padding: 0; margin: 0; }
|
||||
p { margin: 0 0 1em 0; padding: 0; }
|
||||
img {
|
||||
border: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| HEADER |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
#header h1 {
|
||||
margin-top: 30px;
|
||||
font-size: 5em;
|
||||
}
|
||||
|
||||
#header h1 a {
|
||||
color: #ffa;
|
||||
background: inherit;
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#header h1 a:hover {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
color: #555;
|
||||
padding-top: .2em;
|
||||
font-size: 1.2em;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| SEARCH |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
#sform {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
#search-results {
|
||||
text-align: left;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px dotted #666;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| POST |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
.post {
|
||||
padding: 10px 0 10px 0;
|
||||
margin: 5px 0 15px 5px;
|
||||
/* clear: left;*/
|
||||
}
|
||||
|
||||
.post h2 {
|
||||
font-size: 140%;
|
||||
line-height: 1.4em;
|
||||
margin: 5px 0;
|
||||
/* padding-top: 15px;*/
|
||||
}
|
||||
|
||||
.post h3 {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.post h2 a {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.post h2 a:before {
|
||||
content: '# ';
|
||||
}
|
||||
|
||||
.post h2 a:hover {
|
||||
color: #ffa;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.post p {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
p.meta {
|
||||
font-size: 75%;
|
||||
text-align: right;
|
||||
margin-right: 15px;
|
||||
/* border-right: 1px solid #999;*/
|
||||
/* float: left;*/
|
||||
/* width: 75px;*/
|
||||
}
|
||||
|
||||
p.auth {
|
||||
font-size: 85%;
|
||||
font-weight: bold;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| COMMENTS |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
.comment-list li, #preview {
|
||||
background: #666;
|
||||
padding: 5px;
|
||||
margin-bottom: 8px;
|
||||
color: #eee;
|
||||
/*border-right: 20px solid #d3e0ea;*/
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.gravatar {
|
||||
float: right;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| SIDEBAR |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
#sidebar h3 {
|
||||
font-size: 110%;
|
||||
line-height: 1.5em;
|
||||
color: #ff9d47;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 2px;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
#sidebar h3:before {
|
||||
content: "<< ";
|
||||
font-size: small;
|
||||
}
|
||||
#sidebar h3:after {
|
||||
content: " >>";
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
#sidebar h3 a {
|
||||
color: #ff9d47;
|
||||
border-bottom: 1px dotted #ff9d47;
|
||||
}
|
||||
|
||||
#sidebar h3 a:hover {
|
||||
color: #000;
|
||||
background: #ffa;
|
||||
}
|
||||
|
||||
#sidebar ul {
|
||||
text-align: right;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
#sidebar ul li {
|
||||
/* background: url(http://web.archive.org/web/20060321041209/http://sami.samhuri.net/images/theme/small_arrow.png) 45% no-repeat;*/
|
||||
/* padding-left: 12px;*/
|
||||
}
|
||||
|
||||
#sidebar a.feed,
|
||||
#sidebar a.feed:link,
|
||||
#sidebar a.feed:hover {
|
||||
display: inline;
|
||||
border: none;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| FOOTER |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
#footer ul {
|
||||
margin: 0;
|
||||
padding: 10px 0 0 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#footer ul li {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
padding: 0 5px 0 0;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| FORMS |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
input, textarea, select {
|
||||
border: 1px solid #8ab3d1;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.frm-tbl td { vertical-align: top; padding: 5px; }
|
||||
td#frm-btns { text-align: right; }
|
||||
|
||||
#comment_body { height: 220px; }
|
||||
#form-submit-button { background: #d3e0ea; }
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| MISC |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
.powered { border: none; }
|
||||
.powered img { margin-top: 20px; }
|
||||
.pullquote {
|
||||
width: 30%;
|
||||
float:right;
|
||||
font: 150%/1.5em Times, Helvetica, "Times New Roman", serif;
|
||||
color: #666;
|
||||
margin:10px;
|
||||
background: url(http://web.archive.org/web/20060321041209/http://sami.samhuri.net/images/theme/q-close.gif) no-repeat 70% 100% !important;
|
||||
background /**/:url(); /* removing quote graphic in IE5+ */
|
||||
padding: 0 25px 5px 0;
|
||||
}
|
||||
.pullquote:first-letter {
|
||||
background: url(http://web.archive.org/web/20060321041209/http://sami.samhuri.net/images/theme/q-open.gif) no-repeat left top !important;
|
||||
padding:5px 2px 10px 35px!important;
|
||||
padding /**/:0px; /* resetting padding in IE5+ */
|
||||
background /**/: url(); /* removing quote graphic in IE5+ */
|
||||
}
|
||||
|
||||
.light-bg { background: #666; padding: 2px; }
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#errors {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.admintools {
|
||||
float: right;
|
||||
background-color: #fff;
|
||||
font-size: smaller;
|
||||
padding: 0 2px;
|
||||
margin: 0 1px;
|
||||
color: #ccc;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.admintools:hover {
|
||||
color: #c00;
|
||||
border: 1px solid #c00;
|
||||
}
|
||||
|
||||
a[name] { border: none; }
|
||||
|
||||
/* Hides from IE-mac \*/
|
||||
* html .clearfix {height: 1%;}
|
||||
/* End hide from IE-mac */
|
||||
|
||||
#categories li em, #archives li em
|
||||
{
|
||||
color: #98B4D1;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
/* Syntax highlighting */
|
||||
.typocode_ruby .normal {}
|
||||
.typocode_ruby .comment { color: #005; font-style: italic; }
|
||||
.typocode_ruby .keyword { color: #A00; font-weight: bold; }
|
||||
.typocode_ruby .method { color: #077; }
|
||||
.typocode_ruby .class { color: #074; }
|
||||
.typocode_ruby .module { color: #050; }
|
||||
.typocode_ruby .punct { color: #447; font-weight: bold; }
|
||||
.typocode_ruby .symbol { color: #099; }
|
||||
.typocode_ruby .string { color: #944; background: #FFE; }
|
||||
.typocode_ruby .char { color: #F07; }
|
||||
.typocode_ruby .ident { color: #004; }
|
||||
.typocode_ruby .constant { color: #07F; }
|
||||
.typocode_ruby .regex { color: #B66; background: #FEF; }
|
||||
.typocode_ruby .number { color: #F99; }
|
||||
.typocode_ruby .attribute { color: #7BB; }
|
||||
.typocode_ruby .global { color: #7FB; }
|
||||
.typocode_ruby .expr { color: #227; }
|
||||
.typocode_ruby .escape { color: #277; }
|
||||
.typocode_xml .normal {}
|
||||
.typocode_xml .namespace { color: #B66; font-weight: bold; }
|
||||
.typocode_xml .tag { color: #F88; }
|
||||
.typocode_xml .comment { color: #005; font-style: italic; }
|
||||
.typocode_xml .punct { color: #447; font-weight: bold; }
|
||||
.typocode_xml .string { color: #944; }
|
||||
.typocode_xml .number { color: #F99; }
|
||||
.typocode_xml .attribute { color: #BB7; }
|
||||
.typocode_yaml .normal {}
|
||||
.typocode_yaml .document { font-weight: bold; color: #07F; }
|
||||
.typocode_yaml .type { font-weight: bold; color: #05C; }
|
||||
.typocode_yaml .key { color: #F88; }
|
||||
.typocode_yaml .comment { color: #005; font-style: italic; }
|
||||
.typocode_yaml .punct { color: #447; font-weight: bold; }
|
||||
.typocode_yaml .string { color: #944; }
|
||||
.typocode_yaml .number { color: #F99; }
|
||||
.typocode_yaml .time { color: #F99; }
|
||||
.typocode_yaml .date { color: #F99; }
|
||||
.typocode_yaml .ref { color: #944; }
|
||||
.typocode_yaml .anchor { color: #944; }
|
||||
|
||||
.typocode {
|
||||
background-color:#eee;
|
||||
padding:2px;
|
||||
margin:5px;
|
||||
margin-left:1em;
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
||||
.typocode pre {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: monospace;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
|
||||
.typocode .lineno {
|
||||
text-align: right;
|
||||
/* color: #B00;*/
|
||||
font-family: monospace;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Andale Mono", "Lucida Typewriter", "Bitstream Vera Sans Mono", fixed-width, monospace;
|
||||
/* font-size: 120%;*/
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #555;
|
||||
border: 1px dashed #5189ea;
|
||||
margin-bottom: 30px;
|
||||
margin-top: -10px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/*+-------------------------------------------+
|
||||
| TAGLIST |
|
||||
+-------------------------------------------+*/
|
||||
|
||||
ul#taglist li {
|
||||
display: inline;
|
||||
line-height: 3em;
|
||||
}
|
||||
|
||||
.tags .tags0 { font-size: 1.0em; }
|
||||
.tags .tags1 { font-size: 1.2em; }
|
||||
.tags .tags2 { font-size: 1.4em; }
|
||||
.tags .tags3 { font-size: 1.6em; }
|
||||
.tags .tags4 { font-size: 1.8em; }
|
||||
.tags .tags5 { font-size: 2.0em; }
|
||||
.tags .tags6 { font-size: 2.2em; }
|
||||
.tags .tags7 { font-size: 2.4em; }
|
||||
.tags .tags8 { font-size: 2.6em; }
|
||||
.tags .tags9 { font-size: 2.8em; }
|
||||
.tags .tags10 { font-size: 3.0em; }
|
||||
BIN
public/f/menu.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
81
public/f/mephisto_converters-typo-schema_version_61.patch
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
diff -Nupr mephisto_converters/lib/converters/typo/article.rb mephisto_converters-schema_61/lib/converters/typo/article.rb
|
||||
--- mephisto_converters/lib/converters/typo/article.rb 2006-11-23 10:57:06.000000000 -0800
|
||||
+++ mephisto_converters-schema_61/lib/converters/typo/article.rb 2007-05-26 01:54:19.000000000 -0700
|
||||
@@ -1,7 +1,8 @@
|
||||
module Typo
|
||||
class Article < Content
|
||||
- has_many :comments, :dependent => true, :order => "created_at ASC", :class_name => 'Typo::Comment'
|
||||
+ has_many :comments, :dependent => :destroy, :order => "created_at ASC", :class_name => 'Typo::Comment'
|
||||
has_and_belongs_to_many :tags, :class_name => 'Typo::Tag'
|
||||
- has_and_belongs_to_many :categories, :class_name => 'Typo::Category'
|
||||
+ has_many :categorizations, :class_name => 'Typo::Categorization'
|
||||
+ has_many :categories, :class_name => 'Typo::Category', :through => :categorizations
|
||||
end
|
||||
end
|
||||
diff -Nupr mephisto_converters/lib/converters/typo/categorization.rb mephisto_converters-schema_61/lib/converters/typo/categorization.rb
|
||||
--- mephisto_converters/lib/converters/typo/categorization.rb 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ mephisto_converters-schema_61/lib/converters/typo/categorization.rb 2007-05-26 01:44:19.000000000 -0700
|
||||
@@ -0,0 +1,7 @@
|
||||
+module Typo
|
||||
+ class Categorization < ActiveRecord::Base
|
||||
+ establish_connection configurations['typo']
|
||||
+ belongs_to :article, :class_name => 'Typo::Article'
|
||||
+ belongs_to :category, :class_name => 'Typo::Category'
|
||||
+ end
|
||||
+end
|
||||
diff -Nupr mephisto_converters/lib/converters/typo/category.rb mephisto_converters-schema_61/lib/converters/typo/category.rb
|
||||
--- mephisto_converters/lib/converters/typo/category.rb 2006-11-23 10:57:06.000000000 -0800
|
||||
+++ mephisto_converters-schema_61/lib/converters/typo/category.rb 2007-05-26 01:42:02.000000000 -0700
|
||||
@@ -1,6 +1,7 @@
|
||||
module Typo
|
||||
class Category < ActiveRecord::Base
|
||||
establish_connection configurations['typo']
|
||||
- has_and_belongs_to_many :articles, :class_name => 'Typo::Article'
|
||||
+ has_many :categorizations, :class_name => 'Typo::Categorization'
|
||||
+ has_many :articles, :class_name => 'Typo::Article', :through => :categorizations
|
||||
end
|
||||
end
|
||||
diff -Nupr mephisto_converters/lib/converters/typo/comment.rb mephisto_converters-schema_61/lib/converters/typo/comment.rb
|
||||
--- mephisto_converters/lib/converters/typo/comment.rb 2006-11-23 10:57:06.000000000 -0800
|
||||
+++ mephisto_converters-schema_61/lib/converters/typo/comment.rb 2007-05-26 01:54:30.000000000 -0700
|
||||
@@ -1,5 +1,7 @@
|
||||
module Typo
|
||||
- class Comment < Content
|
||||
-# belongs_to :article, :foreign_key => 'parentid', :class_name => 'Typo::Comment'
|
||||
+ class Comment < Feedback
|
||||
+ establish_connection configurations['typo']
|
||||
+ belongs_to :article, :class_name => 'Typo::Article'
|
||||
+ belongs_to :user, :class_name => 'Typo::User'
|
||||
end
|
||||
end
|
||||
diff -Nupr mephisto_converters/lib/converters/typo/feedback.rb mephisto_converters-schema_61/lib/converters/typo/feedback.rb
|
||||
--- mephisto_converters/lib/converters/typo/feedback.rb 1969-12-31 16:00:00.000000000 -0800
|
||||
+++ mephisto_converters-schema_61/lib/converters/typo/feedback.rb 2007-05-26 01:55:28.000000000 -0700
|
||||
@@ -0,0 +1,6 @@
|
||||
+module Typo
|
||||
+ class Feedback < Content
|
||||
+ set_table_name 'feedback'
|
||||
+ establish_connection configurations['typo']
|
||||
+ end
|
||||
+end
|
||||
diff -Nupr mephisto_converters/lib/converters/typo.rb mephisto_converters-schema_61/lib/converters/typo.rb
|
||||
--- mephisto_converters/lib/converters/typo.rb 2006-11-23 10:57:06.000000000 -0800
|
||||
+++ mephisto_converters-schema_61/lib/converters/typo.rb 2007-05-26 01:53:14.000000000 -0700
|
||||
@@ -1,8 +1,10 @@
|
||||
require 'converters/typo/content'
|
||||
require 'converters/typo/page'
|
||||
require 'converters/typo/article'
|
||||
+require 'converters/typo/feedback'
|
||||
require 'converters/typo/comment'
|
||||
require 'converters/typo/category'
|
||||
+require 'converters/typo/categorization'
|
||||
require 'converters/typo/user'
|
||||
require 'converters/typo/tag'
|
||||
|
||||
@@ -77,4 +79,4 @@ class TypoConverter < BaseConverter
|
||||
memo << (sections[::Section.permalink_for(cat.name)] || site.sections.create(:name => cat.name)).id
|
||||
end
|
||||
end
|
||||
-end
|
||||
\ No newline at end of file
|
||||
+end
|
||||
29
public/f/note.html
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<style>
|
||||
html,body { height: 100% }
|
||||
#note { width: 100%; height: 100% }
|
||||
</style>
|
||||
<script>
|
||||
var note, html, timeout;
|
||||
window.addEventListener('load', function() {
|
||||
note = document.getElementById('note');
|
||||
html = document.getElementsByTagName('html')[0];
|
||||
html.addEventListener('keyup', function(ev) {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
timeout = setTimeout(saveNote, 100);
|
||||
});
|
||||
restoreNote();
|
||||
note.focus();
|
||||
});
|
||||
function saveNote() {
|
||||
localStorage.note = note.innerText;
|
||||
timeout = null;
|
||||
}
|
||||
function restoreNote() {
|
||||
note.innerText = localStorage.note || '';
|
||||
}
|
||||
</script>
|
||||
<h1>Notepad (type below, notes persist)</h1>
|
||||
<p id="note" contenteditable></p>
|
||||
</html>
|
||||
BIN
public/f/pacman-tones.zip
Normal file
BIN
public/f/pacman-tones/Pacman Dies.mp3
Normal file
BIN
public/f/pacman-tones/Pacman.mp3
Normal file
BIN
public/f/spinner-blue.gif
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
public/f/spinner.gif
Normal file
|
After Width: | Height: | Size: 2 KiB |
34
public/f/tagify.el
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
(defun wrap-region (left right)
|
||||
"Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right."
|
||||
(interactive)
|
||||
(let ((beg (region-beginning))
|
||||
(end (region-end)))
|
||||
(goto-char beg)
|
||||
(insert left)
|
||||
(goto-char (+ end (length left)))
|
||||
(insert right)
|
||||
(goto-char (+ end (length left) (length right)))))
|
||||
|
||||
(defun tagify-region-or-insert-self (arg)
|
||||
"If there is a visible region, call `tagify-region-or-insert', otherwise
|
||||
call `self-insert-command' passing it any prefix arg given."
|
||||
(interactive "*P")
|
||||
(if (and mark-active transient-mark-mode)
|
||||
(call-interactively 'tagify-region-or-insert-tag)
|
||||
(self-insert-command (prefix-numeric-value arg))))
|
||||
|
||||
(defun tagify-region-or-insert-tag (tag)
|
||||
"If there is a visible region, wrap it in the given HTML/XML tag using
|
||||
`wrap-region'. If any attributes are specified then they are only included
|
||||
in the opening tag.
|
||||
|
||||
Otherwise insert the opening and closing tags and position point between the two."
|
||||
(interactive "*sTag (including attributes): \n")
|
||||
(let* ((open (concat "<" tag ">"))
|
||||
(close (concat "</" (car (split-string tag " ")) ">")))
|
||||
(if (and mark-active transient-mark-mode)
|
||||
(wrap-region open close)
|
||||
(insert (concat open close))
|
||||
(backward-char (length close)))))
|
||||
|
||||
(provide 'tagify)
|
||||
21
public/f/volume.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
Ops = {
|
||||
:+ => [lambda { |x| x + 5 > 100 ? 100 : x + 5 }, "increased"],
|
||||
:- => [lambda { |x| x - 5 < 0 ? 0 : x - 5 } , "decreased"]
|
||||
}
|
||||
|
||||
def vol_op id, vol
|
||||
[Ops[id].first.call(vol), Ops[id].last]
|
||||
end
|
||||
|
||||
op = ARGV.shift.to_sym
|
||||
unless Ops.keys.include?(op)
|
||||
raise "#{op} is not a valid argument. Expected one of: #{Ops.keys.join(', ')}."
|
||||
else
|
||||
`amixer get Master`.split("\n").grep(/%/).first =~ /\[(\d+)/
|
||||
vol = $1.to_i
|
||||
new_vol, action = *vol_op(op, vol)
|
||||
system("amixer set Master #{new_vol}%")
|
||||
system("notify-send --urgency=low --icon=~/.icons/audio-volume-medium.gif --expire-time=500 \"Volume #{action}\" \"#{new_vol}%\"")
|
||||
end
|
||||
49
public/f/wrap-region.el
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
;; help out a TextMate junkie
|
||||
|
||||
(defun wrap-region (left right beg end)
|
||||
"Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(insert left)
|
||||
(goto-char (+ end (length left)))
|
||||
(insert right)))
|
||||
|
||||
(defmacro wrap-region-with-function (left right)
|
||||
"Returns a function which, when called, will interactively `wrap-region-or-insert' using LEFT and RIGHT."
|
||||
`(lambda () (interactive)
|
||||
(wrap-region-or-insert ,left ,right)))
|
||||
|
||||
(defun wrap-region-with-tag-or-insert ()
|
||||
(interactive)
|
||||
(if (and mark-active transient-mark-mode)
|
||||
(call-interactively 'wrap-region-with-tag)
|
||||
(insert "<")))
|
||||
|
||||
(defun wrap-region-with-tag (tag beg end)
|
||||
"Wrap the region in the given HTML/XML tag using `wrap-region'. If any
|
||||
attributes are specified then they are only included in the opening tag."
|
||||
(interactive "*sTag (including attributes): \nr")
|
||||
(let* ((elems (split-string tag " "))
|
||||
(tag-name (car elems))
|
||||
(right (concat "</" tag-name ">")))
|
||||
(if (= 1 (length elems))
|
||||
(wrap-region (concat "<" tag-name ">") right beg end)
|
||||
(wrap-region (concat "<" tag ">") right beg end))))
|
||||
|
||||
(defun wrap-region-or-insert (left right)
|
||||
"Wrap the region with `wrap-region' if an active region is marked, otherwise insert LEFT at point."
|
||||
(interactive)
|
||||
(if (and mark-active transient-mark-mode)
|
||||
(wrap-region left right (region-beginning) (region-end))
|
||||
(insert left)))
|
||||
|
||||
(global-set-key "'" (wrap-region-with-function "'" "'"))
|
||||
(global-set-key "\"" (wrap-region-with-function "\"" "\""))
|
||||
(global-set-key "`" (wrap-region-with-function "`" "`"))
|
||||
(global-set-key "(" (wrap-region-with-function "(" ")"))
|
||||
(global-set-key "[" (wrap-region-with-function "[" "]"))
|
||||
(global-set-key "{" (wrap-region-with-function "{" "}"))
|
||||
(global-set-key "<" 'wrap-region-with-tag-or-insert) ;; I opted not to have a wrap-with-angle-brackets
|
||||
|
||||
(provide 'wrap-region)
|
||||
BIN
public/f/zelda-tones.zip
Normal file
BIN
public/f/zelda-tones/Zelda Achievement.mp3
Normal file
BIN
public/f/zelda-tones/Zelda Item.mp3
Normal file
BIN
public/f/zelda-tones/Zelda Overture.mp3
Normal file
BIN
public/f/zelda-tones/Zelda Secret.mp3
Normal file
BIN
public/f/zelda-tones/Zelda Song of Storms.mp3
Normal file
BIN
public/f/zelda-tones/Zelda Theme.mp3
Normal file
BIN
public/images/blog/ch1-Z-G-4.gif
Normal file
|
After Width: | Height: | Size: 360 B |
BIN
public/images/blog/download.png
Normal file
|
After Width: | Height: | Size: 139 B |
BIN
public/images/blog/keyboard.jpg
Normal file
|
After Width: | Height: | Size: 468 KiB |
BIN
public/images/blog/menu.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
766
public/js/gitter.js
Normal file
|
|
@ -0,0 +1,766 @@
|
|||
/// gitter
|
||||
/// http://github.com/samsonjs/gitter
|
||||
/// @_sjs
|
||||
///
|
||||
/// Copyright 2010 - 2012 Sami Samhuri <sami@samhuri.net>
|
||||
/// MIT License
|
||||
|
||||
(function() {
|
||||
"use strict"
|
||||
|
||||
var global = (function() { return this || (1, eval)('this') }())
|
||||
, isBrowser = 'document' in global
|
||||
, ie
|
||||
|
||||
if (isBrowser) {
|
||||
ie = (function() {
|
||||
var undef
|
||||
, v = 3
|
||||
, div = document.createElement('div')
|
||||
, all = div.getElementsByTagName('i')
|
||||
|
||||
while (
|
||||
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
|
||||
all[0]
|
||||
);
|
||||
|
||||
return v > 4 ? v : undef
|
||||
}())
|
||||
}
|
||||
|
||||
var inherits
|
||||
if ('create' in Object) {
|
||||
// util.inherits from node
|
||||
inherits = function(ctor, superCtor) {
|
||||
ctor.super_ = superCtor
|
||||
ctor.prototype = Object.create(superCtor.prototype, {
|
||||
constructor: {
|
||||
value: ctor,
|
||||
enumerable: false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
else if ([].__proto__) {
|
||||
inherits = function(ctor, superCtor) {
|
||||
ctor.super_ = superCtor
|
||||
ctor.prototype.__proto__ = superCtor.prototype
|
||||
ctor.prototype.constructor = ctor
|
||||
}
|
||||
}
|
||||
else { // ie8
|
||||
var __hasProp = Object.prototype.hasOwnProperty
|
||||
inherits = function(child, parent) {
|
||||
for (var key in parent) {
|
||||
if (__hasProp.call(parent, key)) child[key] = parent[key]
|
||||
}
|
||||
function ctor() { this.constructor = child }
|
||||
ctor.prototype = parent.prototype
|
||||
child.prototype = new ctor
|
||||
child.__super__ = parent.prototype
|
||||
return child
|
||||
}
|
||||
}
|
||||
|
||||
var api = {
|
||||
// Blob
|
||||
blob: function(user, repo, sha, cb) {
|
||||
return new Blob(user, repo, sha, cb)
|
||||
}
|
||||
|
||||
// Branch
|
||||
, branch: function(user, repo, name, cb) {
|
||||
return new Branch(user, repo, name, cb)
|
||||
}
|
||||
|
||||
// Commit
|
||||
, commit: function(user, repo, sha, cb) {
|
||||
return new Commit(user, repo, sha, cb)
|
||||
}
|
||||
|
||||
// Download
|
||||
, download: function(user, repo, id, cb) {
|
||||
return new Download(user, repo, id, cb)
|
||||
}
|
||||
|
||||
// Issue
|
||||
, issue: function(user, repo, id, cb) {
|
||||
return new Issue(user, repo, id, cb)
|
||||
}
|
||||
|
||||
// Organization
|
||||
, org: function(name, cb) {
|
||||
return new Org(name, cb)
|
||||
}
|
||||
, members: function(name, cb) {
|
||||
return new Org(name).fetchMembers(cb)
|
||||
}
|
||||
|
||||
// Repo
|
||||
, repo: function(user, repo, cb) {
|
||||
return new Repo(user, repo, cb)
|
||||
}
|
||||
, branches: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchBranches(cb)
|
||||
}
|
||||
, collaborators: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchCollaborators(cb)
|
||||
}
|
||||
, contributors: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchContributors(cb)
|
||||
}
|
||||
, downloads: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchDownloads(cb)
|
||||
}
|
||||
, forks: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchForks(cb)
|
||||
}
|
||||
, issues: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchIssues(cb)
|
||||
}
|
||||
, languages: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchLanguages(cb)
|
||||
}
|
||||
, tags: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchTags(cb)
|
||||
}
|
||||
, watchers: function(user, repo, cb) {
|
||||
return new Repo(user, repo).fetchWatchers(cb)
|
||||
}
|
||||
|
||||
, ref: function(user, repo, name, cb) {
|
||||
return new Ref(user, repo, name, cb)
|
||||
}
|
||||
|
||||
// Tag
|
||||
, tag: function(user, repo, name, cb) {
|
||||
return new Tag(user, repo, name, cb)
|
||||
}
|
||||
|
||||
// Tree
|
||||
, tree: function(user, repo, sha, cb) {
|
||||
return new Tree(user, repo, sha, cb)
|
||||
}
|
||||
|
||||
// User
|
||||
, user: function(login, cb) {
|
||||
return new User(login, cb)
|
||||
}
|
||||
, followers: function(login, cb) {
|
||||
return new User(login).fetchFollowers(cb)
|
||||
}
|
||||
, following: function(login, cb) {
|
||||
return new User(login).fetchFollowing(cb)
|
||||
}
|
||||
, repos: function(login, cb) {
|
||||
return new User(login).fetchRepos(cb)
|
||||
}
|
||||
, watched: function(login, cb) {
|
||||
return new User(login).fetchWatched(cb)
|
||||
}
|
||||
|
||||
// Why not, expose the resources directly as well.
|
||||
, Blob: Blob
|
||||
, Branch: Branch
|
||||
, Commit: Commit
|
||||
, Download: Download
|
||||
, Issue: Issue
|
||||
, Org: Org
|
||||
, Ref: Ref
|
||||
, Repo: Repo
|
||||
, Tree: Tree
|
||||
, User: User
|
||||
}
|
||||
|
||||
// when running in the browser request is set later, in shim()
|
||||
var request
|
||||
|
||||
if (isBrowser) {
|
||||
shim()
|
||||
global.GITR = api
|
||||
}
|
||||
else {
|
||||
var https = require('https')
|
||||
request = function(options, cb) {
|
||||
var req = https.request(options, function(response) {
|
||||
var bodyParts = []
|
||||
response.on('data', function(b) { bodyParts.push(b) })
|
||||
response.on('end', function() {
|
||||
var body = bodyParts.join('')
|
||||
if (response.statusCode === 200) {
|
||||
cb(null, body, response)
|
||||
}
|
||||
else {
|
||||
console.dir(options, response, body)
|
||||
var err = new Error('http error')
|
||||
err.statusCode = response.statusCode
|
||||
err.body = body
|
||||
cb(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
req.end()
|
||||
req.on('error', function(err) { cb(err) })
|
||||
}
|
||||
module.exports = api
|
||||
}
|
||||
|
||||
|
||||
// Generic Resource //
|
||||
//
|
||||
// Used as the prototype by createResource. Provides
|
||||
// methods for fetching the resource and related
|
||||
// sub-resources.
|
||||
function Resource() {}
|
||||
|
||||
// Fetch data for this resource and pass it to the
|
||||
// callback after mixing the data into the object.
|
||||
// Data is also available via the `data` property.
|
||||
Resource.prototype.fetch = function(cb) {
|
||||
if (this.data) {
|
||||
cb(null, this.data)
|
||||
}
|
||||
else {
|
||||
var self = this
|
||||
fetch(this.path, function(err, data) {
|
||||
// console.log('FETCH', self.path, err, data)
|
||||
if (err) {
|
||||
// console.log(err)
|
||||
}
|
||||
else {
|
||||
self.data = data
|
||||
mixin(self, data)
|
||||
}
|
||||
if (typeof cb === 'function') {
|
||||
cb.call(self, err, data)
|
||||
}
|
||||
})
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
Resource.prototype.fetchSubResource = function(thing, cb) {
|
||||
if (this['_' + thing]) {
|
||||
cb(null, this['_' + thing])
|
||||
}
|
||||
else {
|
||||
var self = this
|
||||
fetch(this.path + '/' + thing, function(err, data) {
|
||||
// console.log('FETCH SUBRESOURCE', self.path, thing, err, data)
|
||||
if (err) {
|
||||
// console.log(self.path, err)
|
||||
}
|
||||
else {
|
||||
self['_' + thing] = data
|
||||
}
|
||||
if (typeof cb === 'function') {
|
||||
cb.call(self, err, data)
|
||||
}
|
||||
})
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
var __slice = Array.prototype.slice
|
||||
|
||||
// Create a resource w/ Resource as the prototype.
|
||||
//
|
||||
// spec: an object with the following properties:
|
||||
//
|
||||
// - constructor: a constructor function
|
||||
// - has: a list of resources belonging to this resource
|
||||
//
|
||||
// Typically the constructor accepts one or more arguments specifying
|
||||
// the name or pieces of info identifying the specific resource and
|
||||
// used to build the URL to fetch it. It also accepts an optional
|
||||
// callback as the last parameter.
|
||||
//
|
||||
// The constructor must set the `path` property which is used to
|
||||
// fetch the resource.
|
||||
//
|
||||
// If a callback is provided then the resource is immediately
|
||||
// fetched and the callback is threaded through to the `fetch`
|
||||
// method. The callback function has the signature
|
||||
// `function(err, data)`.
|
||||
//
|
||||
// The `has` list specifies sub-resources, e.g. a user has repos,
|
||||
// followers, etc. An organization has members.
|
||||
//
|
||||
// Each related sub-resource gets a method named appropriately,
|
||||
// e.g. the User resource has followers so User objects have a
|
||||
// `fetchFollowers` method.
|
||||
function createResource(spec) {
|
||||
var subResources = spec.has ? __slice.call(spec.has) : null
|
||||
, resource = function(/* ..., cb */) {
|
||||
var args = __slice.call(arguments)
|
||||
, lastArgIsCallback = typeof args[args.length - 1] === 'function'
|
||||
, cb = lastArgIsCallback ? args.pop() : null
|
||||
, result = spec.constructor.apply(this, args)
|
||||
|
||||
if (typeof cb === 'function') {
|
||||
this.fetch(cb)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
inherits(resource, Resource)
|
||||
|
||||
if (subResources) {
|
||||
subResources.forEach(function(thing) {
|
||||
var fnName = 'fetch' + toTitleCase(thing)
|
||||
resource.prototype[fnName] = function(cb) {
|
||||
return this.fetchSubResource(thing, cb)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return resource
|
||||
}
|
||||
|
||||
|
||||
// Define Resources //
|
||||
|
||||
var Blob = createResource({
|
||||
constructor: function(user, repo, sha) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.sha = sha
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/blobs/' + sha
|
||||
}
|
||||
})
|
||||
|
||||
var Branch = createResource({
|
||||
constructor: function (user, repo, name) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.name = name
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/refs/heads/' + name
|
||||
}
|
||||
})
|
||||
|
||||
var Commit = createResource({
|
||||
constructor: function Commit(user, repo, sha) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.sha = sha
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/commits/' + sha
|
||||
}
|
||||
})
|
||||
|
||||
var Download = createResource({
|
||||
constructor: function(user, repo, id) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.id = id
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/downloads/' + id
|
||||
}
|
||||
})
|
||||
|
||||
var Issue = createResource({
|
||||
constructor: function(user, repo, id) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.id = id
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/issues/' + id
|
||||
}
|
||||
})
|
||||
|
||||
var Org = createResource({
|
||||
constructor: function(name) {
|
||||
this.name = name
|
||||
this.path = '/orgs/' + encodeURIComponent(nam)
|
||||
}
|
||||
|
||||
, has: 'members repos'.split(' ')
|
||||
})
|
||||
|
||||
var Ref = createResource({
|
||||
constructor: function (user, repo, name) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.name = name
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/refs/' + name
|
||||
}
|
||||
})
|
||||
|
||||
var Repo = createResource({
|
||||
constructor: function(user, repo) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/')
|
||||
}
|
||||
|
||||
, has: ('branches collaborators contributors downloads' +
|
||||
' forks languages tags teams watchers').split(' ')
|
||||
})
|
||||
|
||||
var Tag = createResource({
|
||||
constructor: function (user, repo, name) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.name = name
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/refs/tags/' + name
|
||||
}
|
||||
})
|
||||
|
||||
var Tree = createResource({
|
||||
constructor: function(user, repo, sha) {
|
||||
this.user = user
|
||||
this.repo = repo
|
||||
this.sha = sha
|
||||
this.path = '/repos/' + [user, repo].map(encodeURIComponent).join('/') + '/git/trees/' + sha
|
||||
}
|
||||
})
|
||||
|
||||
var User = createResource({
|
||||
constructor: function(login) {
|
||||
// Allow creating a user from an object returned by the API
|
||||
if (login.login) {
|
||||
login = login.login
|
||||
}
|
||||
this.login = login
|
||||
this.path = '/users/' + encodeURIComponent(login)
|
||||
}
|
||||
|
||||
, has: 'followers following repos watched'.split(' ')
|
||||
})
|
||||
|
||||
|
||||
// Fetch data from github. JSON is parsed and keys are camelized.
|
||||
//
|
||||
// path: the path to the resource
|
||||
// cb: callback(err, data)
|
||||
function fetch(path, cb) {
|
||||
request({ host: 'api.github.com', path: path }, function(err, body, response) {
|
||||
// JSONP requests in the browser return the object directly
|
||||
var data = body
|
||||
|
||||
// Requests in Node return json text, try to parse it
|
||||
if (response && /json/i.exec(response.headers['content-type'])) {
|
||||
try {
|
||||
data = JSON.parse(body)
|
||||
}
|
||||
catch (e) {
|
||||
err = e
|
||||
data = null
|
||||
}
|
||||
}
|
||||
|
||||
cb(err, camelize(data))
|
||||
})
|
||||
}
|
||||
|
||||
// created_at => createdAt
|
||||
function camel(s) {
|
||||
return s.replace(/_(.)/g, function(_, l) { return l.toUpperCase() })
|
||||
}
|
||||
|
||||
// camelize all keys of an object, or all objects in an array
|
||||
function camelize(obj) {
|
||||
if (!obj || typeof obj === 'string') return obj
|
||||
if (Array.isArray(obj)) return obj.map(camelize)
|
||||
if (typeof obj === 'object') {
|
||||
return Object.keys(obj).reduce(function(camelizedObj, k) {
|
||||
camelizedObj[camel(k)] = camelize(obj[k])
|
||||
return camelizedObj
|
||||
}, {})
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
function toTitleCase(s) {
|
||||
return s.charAt(0).toUpperCase() + s.slice(1)
|
||||
}
|
||||
|
||||
function mixin(a, b) {
|
||||
for (var k in b) {
|
||||
if (b.hasOwnProperty(k)) a[k] = b[k]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Browser Utilities //
|
||||
|
||||
function shim() {
|
||||
shimBind()
|
||||
shimES5()
|
||||
shimRequest()
|
||||
}
|
||||
|
||||
function shimBind() {
|
||||
// bind from Prototype
|
||||
if (!Function.prototype.bind) {
|
||||
(function(){
|
||||
function update(array, args) {
|
||||
var arrayLength = array.length, length = args.length
|
||||
while (length--) array[arrayLength + length] = args[length]
|
||||
return array
|
||||
}
|
||||
function merge(array, args) {
|
||||
array = __slice.call(array, 0)
|
||||
return update(array, args)
|
||||
}
|
||||
Function.prototype.bind = function(context) {
|
||||
if (arguments.length < 2 && typeof arguments[0] === 'undefined') return this
|
||||
var __method = this, args = __slice.call(arguments, 1)
|
||||
return function() {
|
||||
var a = merge(args, arguments)
|
||||
return __method.apply(context, a)
|
||||
}
|
||||
}
|
||||
}())
|
||||
}
|
||||
}
|
||||
|
||||
// a few functions from Kris Kowal's es5-shim
|
||||
// https://github.com/kriskowal/es5-shim
|
||||
function shimES5() {
|
||||
var has = Object.prototype.hasOwnProperty
|
||||
|
||||
// ES5 15.2.3.6
|
||||
if (!Object.defineProperty || ie === 8) { // ie8
|
||||
Object.defineProperty = function(object, property, descriptor) {
|
||||
if (typeof descriptor == "object" && object.__defineGetter__) {
|
||||
if (has.call(descriptor, "value")) {
|
||||
if (!object.__lookupGetter__(property) && !object.__lookupSetter__(property)) {
|
||||
// data property defined and no pre-existing accessors
|
||||
object[property] = descriptor.value
|
||||
}
|
||||
if (has.call(descriptor, "get") || has.call(descriptor, "set")) {
|
||||
// descriptor has a value property but accessor already exists
|
||||
throw new TypeError("Object doesn't support this action")
|
||||
}
|
||||
}
|
||||
// fail silently if "writable", "enumerable", or "configurable"
|
||||
// are requested but not supported
|
||||
else if (typeof descriptor.get == "function") {
|
||||
object.__defineGetter__(property, descriptor.get)
|
||||
}
|
||||
if (typeof descriptor.set == "function") {
|
||||
object.__defineSetter__(property, descriptor.set)
|
||||
}
|
||||
}
|
||||
return object
|
||||
}
|
||||
}
|
||||
|
||||
// ES5 15.2.3.14
|
||||
// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
|
||||
if (!Object.keys) { // ie8
|
||||
(function() {
|
||||
var hasDontEnumBug = true,
|
||||
dontEnums = [
|
||||
'toString',
|
||||
'toLocaleString',
|
||||
'valueOf',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'constructor'
|
||||
],
|
||||
dontEnumsLength = dontEnums.length
|
||||
|
||||
for (var key in {"toString": null}) {
|
||||
hasDontEnumBug = false
|
||||
}
|
||||
|
||||
Object.keys = function (object) {
|
||||
|
||||
if (
|
||||
typeof object !== "object" && typeof object !== "function"
|
||||
|| object === null
|
||||
)
|
||||
throw new TypeError("Object.keys called on a non-object")
|
||||
|
||||
var keys = []
|
||||
for (var name in object) {
|
||||
if (has.call(object, name)) {
|
||||
keys.push(name)
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDontEnumBug) {
|
||||
for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
|
||||
var dontEnum = dontEnums[i]
|
||||
if (has.call(object, dontEnum)) {
|
||||
keys.push(dontEnum)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return keys
|
||||
}
|
||||
}())
|
||||
} // Object.keys
|
||||
|
||||
//
|
||||
// Array
|
||||
// =====
|
||||
//
|
||||
|
||||
// ES5 15.4.3.2
|
||||
if (!Array.isArray) {
|
||||
Array.isArray = function(obj) {
|
||||
return Object.prototype.toString.call(obj) == "[object Array]"
|
||||
}
|
||||
}
|
||||
|
||||
// ES5 15.4.4.18
|
||||
if (!Array.prototype.forEach) { // ie8
|
||||
Array.prototype.forEach = function(block, thisObject) {
|
||||
var len = this.length >>> 0
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in this) {
|
||||
block.call(thisObject, this[i], i, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ES5 15.4.4.19
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
|
||||
if (!Array.prototype.map) { // ie8
|
||||
Array.prototype.map = function(fun /*, thisp*/) {
|
||||
var len = this.length >>> 0
|
||||
if (typeof fun != "function") {
|
||||
throw new TypeError()
|
||||
}
|
||||
|
||||
var res = new Array(len)
|
||||
var thisp = arguments[1]
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in this) {
|
||||
res[i] = fun.call(thisp, this[i], i, this)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
// ES5 15.4.4.20
|
||||
if (!Array.prototype.filter) { // ie8
|
||||
Array.prototype.filter = function (block /*, thisp */) {
|
||||
var values = []
|
||||
, thisp = arguments[1]
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (block.call(thisp, this[i])) {
|
||||
values.push(this[i])
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
}
|
||||
|
||||
// ES5 15.4.4.21
|
||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
|
||||
if (!Array.prototype.reduce) { // ie8
|
||||
Array.prototype.reduce = function(fun /*, initial*/) {
|
||||
var len = this.length >>> 0
|
||||
if (typeof fun != "function") {
|
||||
throw new TypeError()
|
||||
}
|
||||
|
||||
// no value to return if no initial value and an empty array
|
||||
if (len == 0 && arguments.length == 1) {
|
||||
throw new TypeError()
|
||||
}
|
||||
|
||||
var i = 0
|
||||
if (arguments.length >= 2) {
|
||||
var rv = arguments[1]
|
||||
} else {
|
||||
do {
|
||||
if (i in this) {
|
||||
rv = this[i++]
|
||||
break
|
||||
}
|
||||
|
||||
// if array contains no values, no initial value to return
|
||||
if (++i >= len) {
|
||||
throw new TypeError()
|
||||
}
|
||||
} while (true)
|
||||
}
|
||||
|
||||
for (; i < len; i++) {
|
||||
if (i in this) {
|
||||
rv = fun.call(null, rv, this[i], i, this)
|
||||
}
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
} // Array.prototype.reduce
|
||||
} // function shimES5()
|
||||
|
||||
// jsonp request, quacks like node's http.request
|
||||
function shimRequest() {
|
||||
var load, _jsonpCounter = 1
|
||||
|
||||
// request is declared earlier
|
||||
request = function(options, cb) {
|
||||
var jsonpCallbackName = '_jsonpCallback' + _jsonpCounter++
|
||||
, url = 'https://' + options.host + options.path + '?callback=GITR.' + jsonpCallbackName
|
||||
GITR[jsonpCallbackName] = function(response) {
|
||||
if (response.meta.status >= 200 && response.meta.status < 300) {
|
||||
cb(null, response.data)
|
||||
}
|
||||
else {
|
||||
var err = new Error('http error')
|
||||
err.statusCode = response.meta.status
|
||||
err.response = response
|
||||
cb(err)
|
||||
}
|
||||
setTimeout(function() { delete GITR[jsonpCallbackName] }, 0)
|
||||
}
|
||||
load(url)
|
||||
}
|
||||
|
||||
// bootstrap loader from LABjs (load is declared earlier)
|
||||
load = function(url) {
|
||||
var oDOC = document
|
||||
, handler
|
||||
, head = oDOC.head || oDOC.getElementsByTagName("head")
|
||||
|
||||
// loading code borrowed directly from LABjs itself
|
||||
// (now removes script elem when done and nullifies its reference --sjs)
|
||||
setTimeout(function () {
|
||||
if ("item" in head) { // check if ref is still a live node list
|
||||
if (!head[0]) { // append_to node not yet ready
|
||||
setTimeout(arguments.callee, 25)
|
||||
return
|
||||
}
|
||||
head = head[0]; // reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
|
||||
}
|
||||
var scriptElem = oDOC.createElement("script")
|
||||
, scriptdone = false
|
||||
|
||||
scriptElem.onload = scriptElem.onreadystatechange = function () {
|
||||
if ((scriptElem.readyState && scriptElem.readyState !== "complete" && scriptElem.readyState !== "loaded") || scriptdone) {
|
||||
return false
|
||||
}
|
||||
scriptElem.onload = scriptElem.onreadystatechange = null
|
||||
scriptElem.parentNode.removeChild(scriptElem)
|
||||
scriptElem = null
|
||||
scriptdone = true
|
||||
}
|
||||
scriptElem.src = url
|
||||
head.insertBefore(scriptElem, head.firstChild)
|
||||
}, 0) // setTimeout
|
||||
|
||||
// required: shim for FF <= 3.5 not having document.readyState
|
||||
if (oDOC.readyState == null && oDOC.addEventListener) {
|
||||
oDOC.readyState = "loading"
|
||||
oDOC.addEventListener("DOMContentLoaded", function handler() {
|
||||
oDOC.removeEventListener("DOMContentLoaded", handler, false)
|
||||
oDOC.readyState = "complete"
|
||||
}, false)
|
||||
}
|
||||
|
||||
} // function load(url)
|
||||
|
||||
} // function shimRequest()
|
||||
|
||||
}())
|
||||
137
public/js/projects.js
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
;(function() {
|
||||
if (typeof console === 'undefined') {
|
||||
console = {log:function(){}}
|
||||
}
|
||||
|
||||
var global = this
|
||||
global.SJS = {
|
||||
proj: function(name) {
|
||||
SJS.projName = name
|
||||
var data = createObjectStore(name)
|
||||
if (document.addEventListener) {
|
||||
document.addEventListener('DOMContentLoaded', ready, false)
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onload', ready)
|
||||
}
|
||||
function ready() {
|
||||
function addClass(el, name) {
|
||||
var c = el.className || name
|
||||
if (!c.match(new RegExp('\b' + name + '\b', 'i'))) c += ' ' + name
|
||||
}
|
||||
function html(id, h) {
|
||||
document.getElementById(id).innerHTML = h
|
||||
}
|
||||
|
||||
var body = document.getElementsByTagName('body')[0]
|
||||
, text
|
||||
if ('innerText' in body) {
|
||||
text = function(id, text) {
|
||||
document.getElementById(id).innerText = text
|
||||
}
|
||||
} else {
|
||||
text = function(id, text) {
|
||||
document.getElementById(id).textContent = text
|
||||
}
|
||||
}
|
||||
|
||||
function highlight(id) {
|
||||
document.getElementById(id).style.className = ' highlight'
|
||||
}
|
||||
function textHighlight(id, t) {
|
||||
text(id, t)
|
||||
document.getElementById(id).className = ' highlight'
|
||||
}
|
||||
function hide(id) {
|
||||
document.getElementById(id).style.display = 'none'
|
||||
}
|
||||
|
||||
function langsByUsage(langs) {
|
||||
return Object.keys(langs).sort(function(a, b) {
|
||||
return langs[a] < langs[b] ? -1 : 1
|
||||
})
|
||||
}
|
||||
|
||||
function listify(things) {
|
||||
return '<ul><li>' + things.join('</li><li>') + '</li></ul>'
|
||||
}
|
||||
|
||||
function updateBranches(name, branches) {
|
||||
function branchLink(b) {
|
||||
return '<a href=https://github.com/samsonjs/' + name + '/tree/' + b.name + '>' + b.name + '</a>'
|
||||
}
|
||||
html('branches', listify(branches.map(branchLink)))
|
||||
}
|
||||
|
||||
function updateContributors(contributors) {
|
||||
function userLink(u) {
|
||||
return '<a href=https://github.com/' + u.login + '>' + (u.name || u.login) + '</a>'
|
||||
}
|
||||
html('contributors', listify(contributors.map(userLink)))
|
||||
}
|
||||
|
||||
function updateLangs(langs) {
|
||||
html('langs', listify(langsByUsage(langs)))
|
||||
}
|
||||
|
||||
function updateN(name, things) {
|
||||
textHighlight('n' + name, things.length)
|
||||
if (things.length === 1) hide(name.charAt(0) + 'plural')
|
||||
}
|
||||
|
||||
var t = data.get('t-' + name)
|
||||
if (!t || +new Date() - t > 3600 * 1000) {
|
||||
console.log('stale ' + String(t))
|
||||
data.set('t-' + name, +new Date())
|
||||
GITR.repo('samsonjs', name)
|
||||
.fetchBranches(function(err, branches) {
|
||||
if (err) {
|
||||
text('branches', '(oops)')
|
||||
} else {
|
||||
data.set('branches', branches)
|
||||
updateBranches(name, branches)
|
||||
}
|
||||
})
|
||||
.fetchLanguages(function(err, langs) {
|
||||
if (err) {
|
||||
text('langs', '(oops)')
|
||||
return
|
||||
}
|
||||
data.set('langs', langs)
|
||||
updateLangs(langs)
|
||||
})
|
||||
.fetchContributors(function(err, users) {
|
||||
if (err) {
|
||||
text('contributors', '(oops)')
|
||||
} else {
|
||||
data.set('contributors', users)
|
||||
updateContributors(users)
|
||||
}
|
||||
})
|
||||
.fetchWatchers(function(err, users) {
|
||||
if (err) {
|
||||
text('nwatchers', '?')
|
||||
} else {
|
||||
data.set('watchers', users)
|
||||
updateN('watchers', users)
|
||||
}
|
||||
})
|
||||
.fetchForks(function(err, repos) {
|
||||
if (err) {
|
||||
text('nforks', '?')
|
||||
} else {
|
||||
data.set('forks', repos)
|
||||
updateN('forks', repos)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('hit ' + t + ' (' + (+new Date() - t) + ')')
|
||||
updateBranches(name, data.get('branches'))
|
||||
updateLangs(data.get('langs'))
|
||||
updateContributors(data.get('contributors'))
|
||||
updateN('watchers', data.get('watchers'))
|
||||
updateN('forks', data.get('forks'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}());
|
||||
92
public/js/storage-polyfill.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
if (!window.localStorage || !window.sessionStorage) (function () {
|
||||
|
||||
var Storage = function (type) {
|
||||
function createCookie(name, value, days) {
|
||||
var date, expires;
|
||||
|
||||
if (days) {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||
expires = "; expires="+date.toGMTString();
|
||||
} else {
|
||||
expires = "";
|
||||
}
|
||||
document.cookie = name+"="+value+expires+"; path=/";
|
||||
}
|
||||
|
||||
function readCookie(name) {
|
||||
var nameEQ = name + "=",
|
||||
ca = document.cookie.split(';'),
|
||||
i, c;
|
||||
|
||||
for (i=0; i < ca.length; i++) {
|
||||
c = ca[i];
|
||||
while (c.charAt(0)==' ') {
|
||||
c = c.substring(1,c.length);
|
||||
}
|
||||
|
||||
if (c.indexOf(nameEQ) == 0) {
|
||||
return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setData(data) {
|
||||
data = JSON.stringify(data);
|
||||
if (type == 'session') {
|
||||
window.top.name = data;
|
||||
} else {
|
||||
createCookie('localStorage', data, 365);
|
||||
}
|
||||
}
|
||||
|
||||
function clearData() {
|
||||
if (type == 'session') {
|
||||
window.top.name = '';
|
||||
} else {
|
||||
createCookie('localStorage', '', 365);
|
||||
}
|
||||
}
|
||||
|
||||
function getData() {
|
||||
var data = type == 'session' ? window.top.name : readCookie('localStorage');
|
||||
return data ? JSON.parse(data) : {};
|
||||
}
|
||||
|
||||
|
||||
// initialise if there's already data
|
||||
var data = getData();
|
||||
|
||||
return {
|
||||
clear: function () {
|
||||
data = {};
|
||||
clearData();
|
||||
},
|
||||
getItem: function (key) {
|
||||
return data[key] || null;
|
||||
},
|
||||
key: function (i) {
|
||||
// not perfect, but works
|
||||
var ctr = 0;
|
||||
for (var k in data) {
|
||||
if (ctr == i) return k;
|
||||
else ctr++;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
removeItem: function (key) {
|
||||
delete data[key];
|
||||
setData(data);
|
||||
},
|
||||
setItem: function (key, value) {
|
||||
data[key] = value+''; // forces the value to a string
|
||||
setData(data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (!window.localStorage) window.localStorage = new Storage('local');
|
||||
if (!window.sessionStorage) window.sessionStorage = new Storage('session');
|
||||
|
||||
}());
|
||||
51
public/js/store.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
;(function() {
|
||||
var global = this
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
global.createObjectStore = function(namespace) {
|
||||
function makeKey(k) {
|
||||
return '--' + namespace + '-' + (k || '')
|
||||
}
|
||||
return {
|
||||
clear: function() {
|
||||
var i = localStorage.length
|
||||
, k
|
||||
, prefix = new RegExp('^' + makeKey())
|
||||
while (--i) {
|
||||
k = localStorage.key(i)
|
||||
if (k.match(prefix)) {
|
||||
localStorage.remove(k)
|
||||
}
|
||||
}
|
||||
},
|
||||
get: function(key) {
|
||||
var val = localStorage[makeKey(key)]
|
||||
try {
|
||||
while (typeof val === 'string') val = JSON.parse(val)
|
||||
} catch (e) {
|
||||
//console.log('string?')
|
||||
}
|
||||
return val
|
||||
},
|
||||
set: function(key, val) {
|
||||
localStorage[makeKey(key)] = typeof val === 'string' ? val : JSON.stringify(val)
|
||||
},
|
||||
remove: function(key) {
|
||||
delete localStorage[makeKey(key)]
|
||||
}
|
||||
}
|
||||
}
|
||||
global.ObjectStore = createObjectStore('default')
|
||||
} else {
|
||||
// Create an in-memory store, should probably fall back to cookies
|
||||
global.createObjectStore = function() {
|
||||
var store = {}
|
||||
return {
|
||||
clear: function() { store = {} },
|
||||
get: function(key) { return store[key] },
|
||||
set: function(key, val) { store[key] = val },
|
||||
remove: function(key) { delete store[key] }
|
||||
}
|
||||
}
|
||||
global.ObjectStore = createObjectStore()
|
||||
}
|
||||
}());
|
||||