Initial check-in after being scrubbed of sensitive data.
|
@ -0,0 +1,13 @@
|
|||
*.pyc
|
||||
*.pyo
|
||||
*#
|
||||
.#*
|
||||
*~
|
||||
js/magnets.js
|
||||
js/sat.js
|
||||
js/wordlist.js
|
||||
node_modules
|
||||
server/magnet_server.js
|
||||
index.html
|
||||
style.css
|
||||
private/
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2012 Elf M. Sternberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,34 @@
|
|||
.PHONY: watch
|
||||
|
||||
HAML=/usr/bin/haml
|
||||
COFFEE = coffee
|
||||
LESSCSS=lessc
|
||||
SED=sed
|
||||
COMPILER=uglifyjs
|
||||
INCLUDES= js/jquery-1.6.2.min.js js/underscore.js js/backbone.js js/jquery-ui-1.8.16.custom.min.js \
|
||||
js/jquery-css-transform.js js/jquery-animate-css-rotate-scale.js js/buzz.js
|
||||
|
||||
all: index.html style.css js/magnets.js js/sat.js js/wordlist.js
|
||||
|
||||
js/magnets.js: src/magnets.coffee
|
||||
$(COFFEE) --compile --lint --output js/ $<
|
||||
|
||||
js/wordlist.js: src/wordlist.coffee
|
||||
$(COFFEE) --compile --lint --bare --output js/ $<
|
||||
$(SED) -i -e '$$ s/;$$//' $@
|
||||
|
||||
js/sat.js: src/sat.coffee
|
||||
$(COFFEE) --compile --lint --output js/ $<
|
||||
|
||||
style.css: src/style.less
|
||||
$(LESSCSS) $< $@
|
||||
|
||||
index.html: src/index.haml
|
||||
$(HAML) --unix-newlines --no-escape-attrs --double-quote-attributes $< > $@
|
||||
|
||||
compile: all
|
||||
cat ${INCLUDES} js/magnets.js | ${COMPILER} > js/compiled.js
|
||||
|
||||
watch:
|
||||
while inotifywait src/*.less src/*.haml src/*.coffee ; do make all; fab send_client ; done
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
@ -0,0 +1,101 @@
|
|||
# Fridgemagnets - A Nifty HTML5 Toy With Some Twitterable Features!
|
||||
|
||||
## Demo
|
||||
|
||||
Main website: [HTML5 Magnets!](http://html5magnets.elfsternberg.com)
|
||||
|
||||
Happy results: [@HTML5Magnets](https://twitter.com/#!/html5magnets)
|
||||
|
||||
## Main Idea
|
||||
|
||||
Fridgemagnets is a straightforward simulation of a relaxing
|
||||
refrigerator poem tileset. It was inspired by
|
||||
[TwitterMagnets](http://twittermagnets.com/), a Flash app written by the
|
||||
brilliant graphic designers at
|
||||
[PlusGood](http://www.plusgood.co.uk/). I have a bit of Flash envy,
|
||||
since I'm not an Adobe developer, and the TwitterMagnets application
|
||||
bugged me. It didn't resize, it didn't do mobile very well, and
|
||||
nobody has a space reserved on their fridge for the poem: a "poem" is
|
||||
just a meaningful arrangement of words deliberately placed in close
|
||||
proximity that seems to convey meaning.
|
||||
|
||||
Fridgemagnets has a lot of new and fun technologies: it uses the audio
|
||||
API, it involves all manner of write-only-DOM tricks to make resizing
|
||||
work well, and it's my first major piece of express.js software. (I
|
||||
originally thought of using Zappa, but decided against it; dispatch is
|
||||
not the biggest thing Node has to deal with, and express by itself
|
||||
works just fine in Coffee.)
|
||||
|
||||
I can now add the Twitter API, the HTML5 Audio API, and some basic
|
||||
game mechanics ([Separate Axis
|
||||
Theorem](http://www.metanetsoftware.com/technique/tutorialA.html) for
|
||||
collision management, anyone?) to my resume.
|
||||
|
||||
This is known to work in later versions of Chrome, Firefox, and IE8+
|
||||
under Windows XP. No promise is implied of it working on your version
|
||||
of those, or any other browser. It's not (yet) phone-ready.
|
||||
|
||||
## Requirements
|
||||
|
||||
Node.js. Most of the subsidiary requirements can be found in the two
|
||||
package.json files. For development purposes Coffeescript, LessCSS,
|
||||
and HAML are in heavy use.
|
||||
|
||||
If you're running the server, you need MySQL. The schema for the
|
||||
MySQL database can be found in the server folder.
|
||||
|
||||
A config file. There's an example in the server folder.
|
||||
|
||||
A twitter developer's account. Get one at dev.twitter.com.
|
||||
|
||||
If you're going to be using the test/deploy routine, inotify-tools and
|
||||
python's "fabric" program are very useful.
|
||||
|
||||
If you're going to make this publicly available, I strongly recommend
|
||||
you run this as its own user in a low-permissions container, behind
|
||||
Nginx and a lot of smarts. Also, the Node.js program "forever" is
|
||||
very useful in keeping the server up.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
[PlusGood](http://www.plusgood.co.uk/), for the inspiration.
|
||||
|
||||
[Emily Richards aka Snowflake](http://ccmixter.org/people/snowflake),
|
||||
for her beautiful music.
|
||||
|
||||
The entire crew at [Nodejitsu](http://nodejitsu.com/), for all the
|
||||
encouragement, even if I don't use their services.
|
||||
|
||||
## CREDITS
|
||||
|
||||
"Ethereal Space" is copyright (c) 2011 Snowflake, licensed under a
|
||||
Creative Commons 3.0 Attribution-Required license.
|
||||
|
||||
jQuery, jQuery UI and associated assets, Buzz.js, and jQuery CSS
|
||||
Transform are copyright their respective owners, and available under
|
||||
a permissive MIT license.
|
||||
|
||||
## LICENSE AND COPYRIGHT NOTICE: NO WARRANTY GRANTED OR IMPLIED
|
||||
|
||||
Copyright (c) 2012 Elf M. Sternberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
- Elf M. Sternberg <elf@pendorwright.com>
|
||||
|
After Width: | Height: | Size: 198 B |
|
@ -0,0 +1,24 @@
|
|||
from fabric.api import *
|
||||
from fabric.decorators import hosts
|
||||
import fabric.contrib
|
||||
|
||||
|
||||
# Devserver
|
||||
# env.user = 'ubuntu'
|
||||
# DEFAULT_HOSTS = [env.user + 'devserver']
|
||||
|
||||
# Production Server
|
||||
env.user = 'htmlmagnets'
|
||||
DEFAULT_HOSTS = [env.user + '@elfsternberg.com']
|
||||
|
||||
def send_server():
|
||||
rsync_cmd = 'rsync -r --progress'
|
||||
local('%s %s %s:%s' % (rsync_cmd, "server/magnet_server.coffee js/wordlist.js private/config.coffee", DEFAULT_HOSTS[0], "server/"))
|
||||
|
||||
def send_client():
|
||||
rsync_cmd = 'rsync -r --progress'
|
||||
content = 'index.html *.jpg *.png *.css js media ui-lightness'
|
||||
local('%s %s %s:%s' % (rsync_cmd, content, DEFAULT_HOSTS[0], "htdocs/"))
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,854 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Buzz, a Javascript HTML5 Audio library
|
||||
// v 1.0.4 beta
|
||||
// Licensed under the MIT license.
|
||||
// http://buzz.jaysalvat.com/
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2011 Jay Salvat
|
||||
// http://jaysalvat.com/
|
||||
// ----------------------------------------------------------------------------
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files ( the "Software" ), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var buzz = {
|
||||
defaults: {
|
||||
autoplay: false,
|
||||
duration: 5000,
|
||||
formats: [],
|
||||
loop: false,
|
||||
placeholder: '--',
|
||||
preload: 'metadata',
|
||||
volume: 80
|
||||
},
|
||||
types: {
|
||||
'mp3': 'audio/mpeg',
|
||||
'ogg': 'audio/ogg',
|
||||
'wav': 'audio/wav',
|
||||
'aac': 'audio/aac',
|
||||
'm4a': 'audio/x-m4a'
|
||||
},
|
||||
sounds: [],
|
||||
el: document.createElement( 'audio' ),
|
||||
|
||||
sound: function( src, options ) {
|
||||
options = options || {};
|
||||
|
||||
var pid = 0,
|
||||
events = [],
|
||||
eventsOnce = {},
|
||||
supported = buzz.isSupported();
|
||||
|
||||
// publics
|
||||
this.load = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.load();
|
||||
return this;
|
||||
};
|
||||
|
||||
this.play = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.play();
|
||||
return this;
|
||||
};
|
||||
|
||||
this.togglePlay = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if ( this.sound.paused ) {
|
||||
this.sound.play();
|
||||
} else {
|
||||
this.sound.pause();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
this.pause = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.pause();
|
||||
return this;
|
||||
};
|
||||
|
||||
this.isPaused = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sound.paused;
|
||||
};
|
||||
|
||||
this.stop = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.setTime( this.getDuration() );
|
||||
this.sound.pause();
|
||||
return this;
|
||||
};
|
||||
|
||||
this.isEnded = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sound.ended;
|
||||
};
|
||||
|
||||
this.loop = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.loop = 'loop';
|
||||
this.bind( 'ended.buzzloop', function() {
|
||||
this.currentTime = 0;
|
||||
this.play();
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
this.unloop = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.removeAttribute( 'loop' );
|
||||
this.unbind( 'ended.buzzloop' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.mute = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.muted = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
this.unmute = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.muted = false;
|
||||
return this;
|
||||
};
|
||||
|
||||
this.toggleMute = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.muted = !this.sound.muted;
|
||||
return this;
|
||||
};
|
||||
|
||||
this.isMuted = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sound.muted;
|
||||
};
|
||||
|
||||
this.setVolume = function( volume ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if ( volume < 0 ) {
|
||||
volume = 0;
|
||||
}
|
||||
if ( volume > 100 ) {
|
||||
volume = 100;
|
||||
}
|
||||
|
||||
this.volume = volume;
|
||||
this.sound.volume = volume / 100;
|
||||
return this;
|
||||
};
|
||||
|
||||
this.getVolume = function() {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.volume;
|
||||
};
|
||||
|
||||
this.increaseVolume = function( value ) {
|
||||
return this.setVolume( this.volume + ( value || 1 ) );
|
||||
};
|
||||
|
||||
this.decreaseVolume = function( value ) {
|
||||
return this.setVolume( this.volume - ( value || 1 ) );
|
||||
};
|
||||
|
||||
this.setTime = function( time ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.whenReady( function() {
|
||||
this.sound.currentTime = time;
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
this.getTime = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var time = Math.round( this.sound.currentTime * 100 ) / 100;
|
||||
return isNaN( time ) ? buzz.defaults.placeholder : time;
|
||||
};
|
||||
|
||||
this.setPercent = function( percent ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.setTime( buzz.fromPercent( percent, this.sound.duration ) );
|
||||
};
|
||||
|
||||
this.getPercent = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var percent = Math.round( buzz.toPercent( this.sound.currentTime, this.sound.duration ) );
|
||||
return isNaN( percent ) ? buzz.defaults.placeholder : percent;
|
||||
};
|
||||
|
||||
this.setSpeed = function( duration ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound.playbackRate = duration;
|
||||
};
|
||||
|
||||
this.getSpeed = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sound.playbackRate;
|
||||
};
|
||||
|
||||
this.getDuration = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var duration = Math.round( this.sound.duration * 100 ) / 100;
|
||||
return isNaN( duration ) ? buzz.defaults.placeholder : duration;
|
||||
};
|
||||
|
||||
this.getPlayed = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return timerangeToArray( this.sound.played );
|
||||
};
|
||||
|
||||
this.getBuffered = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return timerangeToArray( this.sound.buffered );
|
||||
};
|
||||
|
||||
this.getSeekable = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return timerangeToArray( this.sound.seekable );
|
||||
};
|
||||
|
||||
this.getErrorCode = function() {
|
||||
if ( supported && this.sound.error ) {
|
||||
return this.sound.error.code;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
this.getErrorMessage = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch( this.getErrorCode() ) {
|
||||
case 1:
|
||||
return 'MEDIA_ERR_ABORTED';
|
||||
case 2:
|
||||
return 'MEDIA_ERR_NETWORK';
|
||||
case 3:
|
||||
return 'MEDIA_ERR_DECODE';
|
||||
case 4:
|
||||
return 'MEDIA_ERR_SRC_NOT_SUPPORTED';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
this.getStateCode = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sound.readyState;
|
||||
};
|
||||
|
||||
this.getStateMessage = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch( this.getStateCode() ) {
|
||||
case 0:
|
||||
return 'HAVE_NOTHING';
|
||||
case 1:
|
||||
return 'HAVE_METADATA';
|
||||
case 2:
|
||||
return 'HAVE_CURRENT_DATA';
|
||||
case 3:
|
||||
return 'HAVE_FUTURE_DATA';
|
||||
case 4:
|
||||
return 'HAVE_ENOUGH_DATA';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
this.getNetworkStateCode = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.sound.networkState;
|
||||
};
|
||||
|
||||
this.getNetworkStateMessage = function() {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch( this.getNetworkStateCode() ) {
|
||||
case 0:
|
||||
return 'NETWORK_EMPTY';
|
||||
case 1:
|
||||
return 'NETWORK_IDLE';
|
||||
case 2:
|
||||
return 'NETWORK_LOADING';
|
||||
case 3:
|
||||
return 'NETWORK_NO_SOURCE';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
this.set = function( key, value ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.sound[ key ] = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
this.get = function( key ) {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return key ? this.sound[ key ] : this.sound;
|
||||
};
|
||||
|
||||
this.bind = function( types, func ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
types = types.split( ' ' );
|
||||
|
||||
var that = this,
|
||||
efunc = function( e ) { func.call( that, e ); };
|
||||
|
||||
for( var t = 0; t < types.length; t++ ) {
|
||||
var type = types[ t ],
|
||||
idx = type;
|
||||
type = idx.split( '.' )[ 0 ];
|
||||
|
||||
events.push( { idx: idx, func: efunc } );
|
||||
this.sound.addEventListener( type, efunc, true );
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
this.unbind = function( types ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
types = types.split( ' ' );
|
||||
|
||||
for( var t = 0; t < types.length; t++ ) {
|
||||
var idx = types[ t ],
|
||||
type = idx.split( '.' )[ 0 ];
|
||||
|
||||
for( var i = 0; i < events.length; i++ ) {
|
||||
var namespace = events[ i ].idx.split( '.' );
|
||||
if ( events[ i ].idx == idx || ( namespace[ 1 ] && namespace[ 1 ] == idx.replace( '.', '' ) ) ) {
|
||||
this.sound.removeEventListener( type, events[ i ].func, true );
|
||||
delete events[ i ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
this.bindOnce = function( type, func ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
|
||||
eventsOnce[ pid++ ] = false;
|
||||
this.bind( pid + type, function() {
|
||||
if ( !eventsOnce[ pid ] ) {
|
||||
eventsOnce[ pid ] = true;
|
||||
func.call( that );
|
||||
}
|
||||
that.unbind( pid + type );
|
||||
});
|
||||
};
|
||||
|
||||
this.trigger = function( types ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
types = types.split( ' ' );
|
||||
|
||||
for( var t = 0; t < types.length; t++ ) {
|
||||
var idx = types[ t ];
|
||||
|
||||
for( var i = 0; i < events.length; i++ ) {
|
||||
var eventType = events[ i ].idx.split( '.' );
|
||||
if ( events[ i ].idx == idx || ( eventType[ 0 ] && eventType[ 0 ] == idx.replace( '.', '' ) ) ) {
|
||||
var evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent( eventType[ 0 ], false, true );
|
||||
this.sound.dispatchEvent( evt );
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
this.fadeTo = function( to, duration, callback ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if ( duration instanceof Function ) {
|
||||
callback = duration;
|
||||
duration = buzz.defaults.duration;
|
||||
} else {
|
||||
duration = duration || buzz.defaults.duration;
|
||||
}
|
||||
|
||||
var from = this.volume,
|
||||
delay = duration / Math.abs( from - to ),
|
||||
that = this;
|
||||
this.play();
|
||||
|
||||
function doFade() {
|
||||
setTimeout( function() {
|
||||
if ( from < to && that.volume < to ) {
|
||||
that.setVolume( that.volume += 1 );
|
||||
doFade();
|
||||
} else if ( from > to && that.volume > to ) {
|
||||
that.setVolume( that.volume -= 1 );
|
||||
doFade();
|
||||
} else if ( callback instanceof Function ) {
|
||||
callback.apply( that );
|
||||
}
|
||||
}, delay );
|
||||
}
|
||||
this.whenReady( function() {
|
||||
doFade();
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
this.fadeIn = function( duration, callback ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.setVolume(0).fadeTo( 100, duration, callback );
|
||||
};
|
||||
|
||||
this.fadeOut = function( duration, callback ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.fadeTo( 0, duration, callback );
|
||||
};
|
||||
|
||||
this.fadeWith = function( sound, duration ) {
|
||||
if ( !supported ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.fadeOut( duration, function() {
|
||||
this.stop();
|
||||
});
|
||||
|
||||
sound.play().fadeIn( duration );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
this.whenReady = function( func ) {
|
||||
if ( !supported ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
if ( this.sound.readyState === 0 ) {
|
||||
this.bind( 'canplay.buzzwhenready', function() {
|
||||
func.call( that );
|
||||
});
|
||||
} else {
|
||||
func.call( that );
|
||||
}
|
||||
};
|
||||
|
||||
// privates
|
||||
function timerangeToArray( timeRange ) {
|
||||
var array = [],
|
||||
length = timeRange.length - 1;
|
||||
|
||||
for( var i = 0; i <= length; i++ ) {
|
||||
array.push({
|
||||
start: timeRange.start( length ),
|
||||
end: timeRange.end( length )
|
||||
});
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function getExt( filename ) {
|
||||
return filename.split('.').pop();
|
||||
}
|
||||
|
||||
function addSource( sound, src ) {
|
||||
var source = document.createElement( 'source' );
|
||||
source.src = src;
|
||||
if ( buzz.types[ getExt( src ) ] ) {
|
||||
source.type = buzz.types[ getExt( src ) ];
|
||||
}
|
||||
sound.appendChild( source );
|
||||
}
|
||||
|
||||
// init
|
||||
if ( supported ) {
|
||||
|
||||
for(var i in buzz.defaults ) {
|
||||
if(buzz.defaults.hasOwnProperty(i)) {
|
||||
options[ i ] = options[ i ] || buzz.defaults[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
this.sound = document.createElement( 'audio' );
|
||||
|
||||
if ( src instanceof Array ) {
|
||||
for( var j in src ) {
|
||||
if(src.hasOwnProperty(j)) {
|
||||
addSource( this.sound, src[ j ] );
|
||||
}
|
||||
}
|
||||
} else if ( options.formats.length ) {
|
||||
for( var k in options.formats ) {
|
||||
if(options.formats.hasOwnProperty(k)) {
|
||||
addSource( this.sound, src + '.' + options.formats[ k ] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addSource( this.sound, src );
|
||||
}
|
||||
|
||||
if ( options.loop ) {
|
||||
this.loop();
|
||||
}
|
||||
|
||||
if ( options.autoplay ) {
|
||||
this.sound.autoplay = 'autoplay';
|
||||
}
|
||||
|
||||
if ( options.preload === true ) {
|
||||
this.sound.preload = 'auto';
|
||||
} else if ( options.preload === false ) {
|
||||
this.sound.preload = 'none';
|
||||
} else {
|
||||
this.sound.preload = options.preload;
|
||||
}
|
||||
|
||||
this.setVolume( options.volume );
|
||||
|
||||
buzz.sounds.push( this );
|
||||
}
|
||||
},
|
||||
|
||||
group: function( sounds ) {
|
||||
sounds = argsToArray( sounds, arguments );
|
||||
|
||||
// publics
|
||||
this.getSounds = function() {
|
||||
return sounds;
|
||||
};
|
||||
|
||||
this.add = function( soundArray ) {
|
||||
soundArray = argsToArray( soundArray, arguments );
|
||||
for( var a = 0; a < soundArray.length; a++ ) {
|
||||
sounds.push( soundArray[ a ] );
|
||||
}
|
||||
};
|
||||
|
||||
this.remove = function( soundArray ) {
|
||||
soundArray = argsToArray( soundArray, arguments );
|
||||
for( var a = 0; a < soundArray.length; a++ ) {
|
||||
for( var i = 0; i < sounds.length; i++ ) {
|
||||
if ( sounds[ i ] == soundArray[ a ] ) {
|
||||
delete sounds[ i ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.load = function() {
|
||||
fn( 'load' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.play = function() {
|
||||
fn( 'play' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.togglePlay = function( ) {
|
||||
fn( 'togglePlay' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.pause = function( time ) {
|
||||
fn( 'pause', time );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.stop = function() {
|
||||
fn( 'stop' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.mute = function() {
|
||||
fn( 'mute' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.unmute = function() {
|
||||
fn( 'unmute' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.toggleMute = function() {
|
||||
fn( 'toggleMute' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.setVolume = function( volume ) {
|
||||
fn( 'setVolume', volume );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.increaseVolume = function( value ) {
|
||||
fn( 'increaseVolume', value );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.decreaseVolume = function( value ) {
|
||||
fn( 'decreaseVolume', value );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.loop = function() {
|
||||
fn( 'loop' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.unloop = function() {
|
||||
fn( 'unloop' );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.setTime = function( time ) {
|
||||
fn( 'setTime', time );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.setduration = function( duration ) {
|
||||
fn( 'setduration', duration );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.set = function( key, value ) {
|
||||
fn( 'set', key, value );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.bind = function( type, func ) {
|
||||
fn( 'bind', type, func );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.unbind = function( type ) {
|
||||
fn( 'unbind', type );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.bindOnce = function( type, func ) {
|
||||
fn( 'bindOnce', type, func );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.trigger = function( type ) {
|
||||
fn( 'trigger', type );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.fade = function( from, to, duration, callback ) {
|
||||
fn( 'fade', from, to, duration, callback );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.fadeIn = function( duration, callback ) {
|
||||
fn( 'fadeIn', duration, callback );
|
||||
return this;
|
||||
};
|
||||
|
||||
this.fadeOut = function( duration, callback ) {
|
||||
fn( 'fadeOut', duration, callback );
|
||||
return this;
|
||||
};
|
||||
|
||||
// privates
|
||||
function fn() {
|
||||
var args = argsToArray( null, arguments ),
|
||||
func = args.shift();
|
||||
|
||||
for( var i = 0; i < sounds.length; i++ ) {
|
||||
sounds[ i ][ func ].apply( sounds[ i ], args );
|
||||
}
|
||||
}
|
||||
|
||||
function argsToArray( array, args ) {
|
||||
return ( array instanceof Array ) ? array : Array.prototype.slice.call( args );
|
||||
}
|
||||
},
|
||||
|
||||
all: function() {
|
||||
return new buzz.group( buzz.sounds );
|
||||
},
|
||||
|
||||
isSupported: function() {
|
||||
return !!buzz.el.canPlayType;
|
||||
},
|
||||
|
||||
isOGGSupported: function() {
|
||||
return !!buzz.el.canPlayType && buzz.el.canPlayType( 'audio/ogg; codecs="vorbis"' );
|
||||
},
|
||||
|
||||
isWAVSupported: function() {
|
||||
return !!buzz.el.canPlayType && buzz.el.canPlayType( 'audio/wav; codecs="1"' );
|
||||
},
|
||||
|
||||
isMP3Supported: function() {
|
||||
return !!buzz.el.canPlayType && buzz.el.canPlayType( 'audio/mpeg;' );
|
||||
},
|
||||
|
||||
isAACSupported: function() {
|
||||
return !!buzz.el.canPlayType && ( buzz.el.canPlayType( 'audio/x-m4a;' ) || buzz.el.canPlayType( 'audio/aac;' ) );
|
||||
},
|
||||
|
||||
toTimer: function( time, withHours ) {
|
||||
var h, m, s;
|
||||
h = Math.floor( time / 3600 );
|
||||
h = isNaN( h ) ? '--' : ( h >= 10 ) ? h : '0' + h;
|
||||
m = withHours ? Math.floor( time / 60 % 60 ) : Math.floor( time / 60 );
|
||||
m = isNaN( m ) ? '--' : ( m >= 10 ) ? m : '0' + m;
|
||||
s = Math.floor( time % 60 );
|
||||
s = isNaN( s ) ? '--' : ( s >= 10 ) ? s : '0' + s;
|
||||
return withHours ? h + ':' + m + ':' + s : m + ':' + s;
|
||||
},
|
||||
|
||||
fromTimer: function( time ) {
|
||||
var splits = time.toString().split( ':' );
|
||||
if ( splits && splits.length == 3 ) {
|
||||
time = ( parseInt( splits[ 0 ], 10 ) * 3600 ) + ( parseInt(splits[ 1 ], 10 ) * 60 ) + parseInt( splits[ 2 ], 10 );
|
||||
}
|
||||
if ( splits && splits.length == 2 ) {
|
||||
time = ( parseInt( splits[ 0 ], 10 ) * 60 ) + parseInt( splits[ 1 ], 10 );
|
||||
}
|
||||
return time;
|
||||
},
|
||||
|
||||
toPercent: function( value, total, decimal ) {
|
||||
var r = Math.pow( 10, decimal || 0 );
|
||||
|
||||
return Math.round( ( ( value * 100 ) / total ) * r ) / r;
|
||||
},
|
||||
|
||||
fromPercent: function( percent, total, decimal ) {
|
||||
var r = Math.pow( 10, decimal || 0 );
|
||||
|
||||
return Math.round( ( ( total / 100 ) * percent ) * r ) / r;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,135 @@
|
|||
(function ($) {
|
||||
// Monkey patch jQuery 1.3.1+ to add support for setting or animating CSS
|
||||
// scale and rotation independently.
|
||||
// 2009-2010 Zachary Johnson www.zachstronaut.com
|
||||
// Updated 2010.11.06
|
||||
var rotateUnits = 'deg';
|
||||
|
||||
$.fn.rotate = function (val)
|
||||
{
|
||||
var style = $(this).css('transform') || 'none';
|
||||
|
||||
if (typeof val == 'undefined')
|
||||
{
|
||||
if (style)
|
||||
{
|
||||
var m = style.match(/rotate\(([^)]+)\)/);
|
||||
if (m && m[1])
|
||||
{
|
||||
return m[1];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var m = val.toString().match(/^(-?\d+(\.\d+)?)(.+)?$/);
|
||||
if (m)
|
||||
{
|
||||
if (m[3])
|
||||
{
|
||||
rotateUnits = m[3];
|
||||
}
|
||||
|
||||
$(this).css(
|
||||
'transform',
|
||||
style.replace(/none|rotate\([^)]*\)/, '') + 'rotate(' + m[1] + rotateUnits + ')'
|
||||
);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Note that scale is unitless.
|
||||
$.fn.scale = function (val, duration, options)
|
||||
{
|
||||
var style = $(this).css('transform');
|
||||
|
||||
if (typeof val == 'undefined')
|
||||
{
|
||||
if (style)
|
||||
{
|
||||
var m = style.match(/scale\(([^)]+)\)/);
|
||||
if (m && m[1])
|
||||
{
|
||||
return m[1];
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$(this).css(
|
||||
'transform',
|
||||
style.replace(/none|scale\([^)]*\)/, '') + 'scale(' + val + ')'
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// fx.cur() must be monkey patched because otherwise it would always
|
||||
// return 0 for current rotate and scale values
|
||||
var curProxied = $.fx.prototype.cur;
|
||||
$.fx.prototype.cur = function ()
|
||||
{
|
||||
if (this.prop == 'rotate')
|
||||
{
|
||||
return parseFloat($(this.elem).rotate());
|
||||
}
|
||||
else if (this.prop == 'scale')
|
||||
{
|
||||
return parseFloat($(this.elem).scale());
|
||||
}
|
||||
|
||||
return curProxied.apply(this, arguments);
|
||||
}
|
||||
|
||||
$.fx.step.rotate = function (fx)
|
||||
{
|
||||
$(fx.elem).rotate(fx.now + rotateUnits);
|
||||
}
|
||||
|
||||
$.fx.step.scale = function (fx)
|
||||
{
|
||||
$(fx.elem).scale(fx.now);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Starting on line 3905 of jquery-1.3.2.js we have this code:
|
||||
|
||||
// We need to compute starting value
|
||||
if ( unit != "px" ) {
|
||||
self.style[ name ] = (end || 1) + unit;
|
||||
start = ((end || 1) / e.cur(true)) * start;
|
||||
self.style[ name ] = start + unit;
|
||||
}
|
||||
|
||||
This creates a problem where we cannot give units to our custom animation
|
||||
because if we do then this code will execute and because self.style[name]
|
||||
does not exist where name is our custom animation's name then e.cur(true)
|
||||
will likely return zero and create a divide by zero bug which will set
|
||||
start to NaN.
|
||||
|
||||
The following monkey patch for animate() gets around this by storing the
|
||||
units used in the rotation definition and then stripping the units off.
|
||||
|
||||
*/
|
||||
|
||||
var animateProxied = $.fn.animate;
|
||||
$.fn.animate = function (prop)
|
||||
{
|
||||
if (typeof prop['rotate'] != 'undefined')
|
||||
{
|
||||
var m = prop['rotate'].toString().match(/^(([+-]=)?(-?\d+(\.\d+)?))(.+)?$/);
|
||||
if (m && m[5])
|
||||
{
|
||||
rotateUnits = m[5];
|
||||
}
|
||||
|
||||
prop['rotate'] = m[1];
|
||||
}
|
||||
|
||||
return animateProxied.apply(this, arguments);
|
||||
}
|
||||
})(jQuery);
|
|
@ -0,0 +1,112 @@
|
|||
(function ($) {
|
||||
// Monkey patch jQuery 1.3.1+ css() method to support CSS 'transform'
|
||||
// property uniformly across Safari/Chrome/Webkit, Firefox 3.5+, IE 9+, and Opera 11+.
|
||||
// 2009-2011 Zachary Johnson www.zachstronaut.com
|
||||
// Updated 2011.05.04 (May the fourth be with you!)
|
||||
function getTransformProperty(element)
|
||||
{
|
||||
// Try transform first for forward compatibility
|
||||
// In some versions of IE9, it is critical for msTransform to be in
|
||||
// this list before MozTranform.
|
||||
var properties = ['transform', 'WebkitTransform', 'msTransform', 'MozTransform', 'OTransform'];
|
||||
var p;
|
||||
while (p = properties.shift())
|
||||
{
|
||||
if (typeof element.style[p] != 'undefined')
|
||||
{
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
// Default to transform also
|
||||
return 'transform';
|
||||
}
|
||||
|
||||
var _propsObj = null;
|
||||
|
||||
var proxied = $.fn.css;
|
||||
$.fn.css = function (arg, val)
|
||||
{
|
||||
// Temporary solution for current 1.6.x incompatibility, while
|
||||
// preserving 1.3.x compatibility, until I can rewrite using CSS Hooks
|
||||
if (_propsObj === null)
|
||||
{
|
||||
if (typeof $.cssProps != 'undefined')
|
||||
{
|
||||
_propsObj = $.cssProps;
|
||||
}
|
||||
else if (typeof $.props != 'undefined')
|
||||
{
|
||||
_propsObj = $.props;
|
||||
}
|
||||
else
|
||||
{
|
||||
_propsObj = {}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the correct browser specific property and setup the mapping using
|
||||
// $.props which is used internally by jQuery.attr() when setting CSS
|
||||
// properties via either the css(name, value) or css(properties) method.
|
||||
// The problem with doing this once outside of css() method is that you
|
||||
// need a DOM node to find the right CSS property, and there is some risk
|
||||
// that somebody would call the css() method before body has loaded or any
|
||||
// DOM-is-ready events have fired.
|
||||
if
|
||||
(
|
||||
typeof _propsObj['transform'] == 'undefined'
|
||||
&&
|
||||
(
|
||||
arg == 'transform'
|
||||
||
|
||||
(
|
||||
typeof arg == 'object'
|
||||
&& typeof arg['transform'] != 'undefined'
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
_propsObj['transform'] = getTransformProperty(this.get(0));
|
||||
}
|
||||
|
||||
// We force the property mapping here because jQuery.attr() does
|
||||
// property mapping with jQuery.props when setting a CSS property,
|
||||
// but curCSS() does *not* do property mapping when *getting* a
|
||||
// CSS property. (It probably should since it manually does it
|
||||
// for 'float' now anyway... but that'd require more testing.)
|
||||
//
|
||||
// But, only do the forced mapping if the correct CSS property
|
||||
// is not 'transform' and is something else.
|
||||
if (_propsObj['transform'] != 'transform')
|
||||
{
|
||||
// Call in form of css('transform' ...)
|
||||
if (arg == 'transform')
|
||||
{
|
||||
arg = _propsObj['transform'];
|
||||
|
||||
// User wants to GET the transform CSS, and in jQuery 1.4.3
|
||||
// calls to css() for transforms return a matrix rather than
|
||||
// the actual string specified by the user... avoid that
|
||||
// behavior and return the string by calling jQuery.style()
|
||||
// directly
|
||||
if (typeof val == 'undefined' && jQuery.style)
|
||||
{
|
||||
return jQuery.style(this.get(0), arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Call in form of css({'transform': ...})
|
||||
else if
|
||||
(
|
||||
typeof arg == 'object'
|
||||
&& typeof arg['transform'] != 'undefined'
|
||||
)
|
||||
{
|
||||
arg[_propsObj['transform']] = arg['transform'];
|
||||
delete arg['transform'];
|
||||
}
|
||||
}
|
||||
|
||||
return proxied.apply(this, arguments);
|
||||
};
|
||||
})(jQuery);
|
After Width: | Height: | Size: 352 KiB |
|
@ -0,0 +1,10 @@
|
|||
module.exports =
|
||||
twitter:
|
||||
consumer_key: "YOUR TWITTER CONSUMER KEY"
|
||||
consumer_private_key: "YOUR TWITTER SECRET KEY"
|
||||
access_token_key: "YOUR TWITTER ONE TIME ACCESS KEY"
|
||||
access_token_secret: "YOUR TWITTER ONE TIME ACCESS SECRET"
|
||||
tracker:
|
||||
database: 'fridgemagnets'
|
||||
username: 'fridgemagnets'
|
||||
password: 'some witty password here'
|
|
@ -0,0 +1,151 @@
|
|||
express = require 'express'
|
||||
mysql = require('db-mysql')
|
||||
OAuth = require('oauth').OAuth
|
||||
util = require('util')
|
||||
config = require('./config')
|
||||
fs = require('fs')
|
||||
|
||||
wordlist = JSON.parse(fs.readFileSync('./wordlist.js', 'utf-8'))
|
||||
wordstream = (i.w for i in wordlist).join(' ')
|
||||
|
||||
body_to_haiku = (lines) ->
|
||||
ret = (for words in lines
|
||||
line = words[0].w
|
||||
for word in words[1...words.length]
|
||||
line += if word.s == 1 then word.w else ' ' + word.w
|
||||
line).join(" / ")
|
||||
console.log(ret)
|
||||
ret
|
||||
|
||||
|
||||
class AddressTracker
|
||||
|
||||
constructor: (database, username, password) ->
|
||||
@db = new mysql.Database({
|
||||
"hostname": "localhost"
|
||||
"user": username
|
||||
"password": password
|
||||
"database": database})
|
||||
@db.on('ready', () -> @connection = this)
|
||||
@db.on('error', () -> console.log(arguments))
|
||||
|
||||
connect: (cb) ->
|
||||
atrack = @
|
||||
@db.connect () ->
|
||||
atrack.connection = this
|
||||
cb.apply(this, arguments)
|
||||
|
||||
validate: (ip_address, message, cb) ->
|
||||
yesterday = new Date((new Date()).valueOf() - 1000 * 86400)
|
||||
connection = @connection
|
||||
|
||||
connection.query().
|
||||
select('*').
|
||||
from('tweets').
|
||||
where('address = ? and entered > ?', [ip_address, yesterday]).
|
||||
execute (err, rows, cols) ->
|
||||
|
||||
return cb(err, null) if (err)
|
||||
return cb("You've used up your allotted number of tweets today", null) if rows.length > 10
|
||||
|
||||
connection.query().
|
||||
select('*').
|
||||
from('tweets').
|
||||
where('tweet = ?', [body_to_haiku(message.message)]).
|
||||
execute (err, rows, cols) ->
|
||||
|
||||
return cb(err, null) if (err)
|
||||
return cb("You've already sent that poem!", null) if rows.length > 0
|
||||
|
||||
connection.query().
|
||||
insert('tweets', ['address', 'tweet', 'entered'], [ip_address, body_to_haiku(message.message), (new Date())]).
|
||||
execute (err, result) ->
|
||||
return cb(err, null) if err
|
||||
cb(null, result)
|
||||
|
||||
|
||||
class TwitterPoster
|
||||
constructor: ->
|
||||
@oauth = new OAuth(
|
||||
"https://api.twitter.com/oauth/request_token",
|
||||
"https://api.twitter.com/oauth/access_token",
|
||||
config.twitter.consumer_key,
|
||||
config.twitter.consumer_private_key,
|
||||
"1.0",
|
||||
null,
|
||||
"HMAC-SHA1"
|
||||
)
|
||||
|
||||
post: (message, callback) ->
|
||||
@oauth.post(
|
||||
"http://api.twitter.com/1/statuses/update.json",
|
||||
config.twitter.access_token_key,
|
||||
config.twitter.access_token_secret,
|
||||
{"status": body_to_haiku(message.message) },
|
||||
"application/json",
|
||||
(error, data, response2) ->
|
||||
if error
|
||||
console.log(error) if error
|
||||
callback(error, null)
|
||||
return
|
||||
callback(null, data)
|
||||
)
|
||||
|
||||
|
||||
app = module.exports = express.createServer()
|
||||
|
||||
# Configuration
|
||||
app.configure ->
|
||||
app.use express.bodyParser()
|
||||
app.use express.methodOverride()
|
||||
app.use express.logger()
|
||||
app.use app.router
|
||||
|
||||
|
||||
app.configure 'development', ->
|
||||
app.use express.errorHandler
|
||||
dumpExceptions: true
|
||||
showStack: true
|
||||
|
||||
app.configure 'production', ->
|
||||
app.use express.errorHandler()
|
||||
|
||||
all_good_words = (lines) ->
|
||||
for words in lines
|
||||
for word in words
|
||||
if not (new RegExp('\\b' + word + '\\b')).test(wordstream)
|
||||
return false
|
||||
return true
|
||||
|
||||
address_tracker = new AddressTracker(config.tracker.database, config.tracker.username, config.tracker.password)
|
||||
twitter_poster = new TwitterPoster()
|
||||
|
||||
# Our single route
|
||||
|
||||
app.post '/poems/', (req, res) ->
|
||||
if not req.body? or not req.body.message?
|
||||
res.send({error: true, code: -1, message: "We did not receive a poem."})
|
||||
return
|
||||
|
||||
if not all_good_words(req.body.message)
|
||||
res.send({error: true, code: -1, message: "ERROR -5: HACKSTOP."})
|
||||
return
|
||||
|
||||
address_tracker.validate req.headers['x-forwarded-for'], req.body, (err, result) ->
|
||||
if err != null
|
||||
console.log(err)
|
||||
res.send({error: true, code: 1, message: err})
|
||||
return
|
||||
|
||||
twitter_poster.post req.body, (err, result) ->
|
||||
if err != null
|
||||
console.log(err)
|
||||
res.send({error: true, code: 2, message: err})
|
||||
return
|
||||
res.send({error: false, message: result})
|
||||
|
||||
address_tracker.connect () ->
|
||||
app.listen 8012
|
||||
console.log "Express server listening on port %d in %s mode", app.address().port, app.settings.env
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "FridgemagnetServer",
|
||||
"description": "A Twitter Forwarding Serverour CLI formatting friend.",
|
||||
"version": "0.0.1",
|
||||
"author": "Elf M. Sternberg <elf@pendorwright.com>",
|
||||
"dependencies": {
|
||||
"coffee-script": "1.2.0",
|
||||
"oauth": "0.9.6",
|
||||
"express": "2.5.8",
|
||||
"forever": "0.8.5",
|
||||
"db-mysql": "0.7.6"
|
||||
},
|
||||
"main": "./magnet_server",
|
||||
"engines": { "node": ">= 0.6.2" }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
BEGIN;
|
||||
CREATE TABLE tweets (
|
||||
address CHAR(42) NOT NULL,
|
||||
tweet TEXT NOT NULL,
|
||||
entered DATETIME NOT NULL
|
||||
);
|
||||
COMMIT;
|
|
@ -0,0 +1,36 @@
|
|||
!!! 5
|
||||
%html{:xmlns => "http://www.w3.org/1999/xhtml"}
|
||||
%head
|
||||
%meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
|
||||
%meta{"http-equiv" => "Acesss-Control-Allow-Origin", :content => "*"}/
|
||||
%title Fridge Magnets in HTML5
|
||||
%link{:href => "style.css", :rel => "stylesheet", :type => "text/css"}/
|
||||
%link{:href => "ui-lightness/jquery-ui-1.8.18.custom.css", :rel => "stylesheet", :type => "text/css"}/
|
||||
%body
|
||||
#board
|
||||
#results
|
||||
#footer
|
||||
#stripe
|
||||
#muteunmute(data-state='on')
|
||||
%img(src="unmute.png")
|
||||
%button(id="shuffler") Shuffle
|
||||
|
||||
%p#f1
|
||||
HTML5 implementation by <a href="http://elfsternberg.com">Elf M. Sternberg</a>. You can see all our poems
|
||||
<a href="https://twitter.com/#!/html5magnets">@html5magnets</a> on Twitter.
|
||||
#f2
|
||||
%div
|
||||
Comments and feedback to <a href="mailto:elf.sternberg@gmail.com">elf.sternberg@gmail.com</a> | inspired by <a href="http://twittermagnets.com/">twittermagents.com</a> and an allergic reaction to all things flash.</p>
|
||||
%p The music is <em><span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Sound" property="dc:title" rel="dc:type">Ethereal Space</span></em> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://ccmixter.org/files/snowflake/33318" property="cc:attributionName" rel="cc:attributionURL">snowflake</a> and is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution (3.0)</a> license.
|
||||
%div(style="clear:both")/
|
||||
|
||||
#message(style="display: none")
|
||||
%p
|
||||
|
||||
%script{:src => "js/jquery-1.7.1.min.js", :type => "text/javascript"}
|
||||
%script{:src => "js/jquery-ui-1.8.18.custom.min.js", :type => "text/javascript"}
|
||||
%script{:src => "js/jquery-css-transform.js", :type => "text/javascript"}
|
||||
%script{:src => "js/jquery-animate-css-rotate-scale.js", :type => "text/javascript"}
|
||||
%script{:src => "js/buzz.js", :type => "text/javascript"}
|
||||
%script{:src => "js/sat.js", :type => "text/javascript"}
|
||||
%script{:src => "js/magnets.js", :type => "text/javascript"}
|
|
@ -0,0 +1,530 @@
|
|||
SUFFIX = 1
|
||||
PREFIX = 2
|
||||
|
||||
|
||||
# Average number of words visible on any given iteration.
|
||||
AVG_VISIBLE = 60
|
||||
|
||||
clone = (obj) ->
|
||||
return obj if not obj? or typeof obj isnt 'object'
|
||||
newInstance = new obj.constructor()
|
||||
for key of obj
|
||||
newInstance[key] = clone obj[key]
|
||||
newInstance
|
||||
|
||||
|
||||
HEIGHT_FUZZ = 8
|
||||
WIDTH_FUZZ = 6
|
||||
|
||||
# A dimensioned object is one that appears on the board: it has an X
|
||||
# and Y coordinate, a width and a height. From this, we can create a
|
||||
# bounding box using the "shape" function. Dimensioned objects can be
|
||||
# compared to other dimensioned objects to assert whether or not
|
||||
# they're in collision. Some objects have bounding boxes that pull in
|
||||
# or push out the borders abstractly, in order to provide for "fuzzy"
|
||||
# collisions that correspond to drop shadows or similar visual effects.
|
||||
|
||||
shape = (x, y, w, h) -> [{x: x, y: y}, {x: x + w, y: y}, {x: x + w, y: y + h}, {x: x, y: y + h}]
|
||||
|
||||
class Dimensioned
|
||||
_width: null
|
||||
_height: null
|
||||
_left_p: null
|
||||
_top_p: null
|
||||
_left: null
|
||||
_top: null
|
||||
_pos: null
|
||||
|
||||
constructor: (@el) ->
|
||||
|
||||
unset_dims: ->
|
||||
@_left = @_top = @_width = @_height = @_pos = null
|
||||
|
||||
reset_dims: ->
|
||||
@unset_dims()
|
||||
[@left(), @top(), @width(), @height()]
|
||||
|
||||
positioned: -> return @_width? and @height?
|
||||
|
||||
visibleReposition: ->
|
||||
@reposition()
|
||||
@el.css {top: @top(), left: @left()}
|
||||
@
|
||||
|
||||
reposition: ->
|
||||
parent = @el.offsetParent()
|
||||
[@_top, @_left] = [parseInt(@_top_p * parent.height()), parseInt(@_left_p * parent.width())]
|
||||
@_pos = {left: @_left, top: @_top}
|
||||
@
|
||||
|
||||
width: -> @_width = if @_width? then @_width else @el.outerWidth()
|
||||
height: -> @_height = if @_height? then @_height else @el.outerHeight()
|
||||
pos: -> @_pos = if @_pos? then @_pos else @el.position()
|
||||
|
||||
left: -> @_left = if @_left?
|
||||
@_left
|
||||
else
|
||||
@_left = @pos().left
|
||||
@_left_p = @_left / @el.offsetParent().width()
|
||||
@_left
|
||||
|
||||
top: -> @_top = if @_top?
|
||||
@_top
|
||||
else
|
||||
@_top = @pos().top
|
||||
@_top_p = @_top / @el.offsetParent().height()
|
||||
@_top
|
||||
|
||||
dims: -> [@width(), @height()]
|
||||
shape: ->
|
||||
shape @left(), @top(), @width(), @height()
|
||||
|
||||
|
||||
# I can't decide if this is the right way to go, with a two-pass "set
|
||||
# it all up, then make it all blow up," but it works quite well, all
|
||||
# things considered. And after much consideration (like, one minute
|
||||
# of realizing I never, ever used the features) it became obvious I
|
||||
# didn't need Dimensioned.
|
||||
|
||||
class Heart
|
||||
|
||||
constructor: (@parent, @top, @left, symbol) ->
|
||||
dv = '<div class="heart" style="display:none;top:' + parseInt(@top) + 'px;left:' + \
|
||||
parseInt(@left) + 'px' + '">' + symbol + '</div>'
|
||||
@el = $(dv)
|
||||
@el.css {'font-size': 'larger'} if Math.random() > 0.6
|
||||
@rot_dist = parseInt(90 * Math.random()) * (if Math.random() < 0.5 then 1 else -1)
|
||||
[@dir, @dst, @dur] = [Math.random() * 2 * Math.PI, Math.random() * 110, Math.random() * 1200 + 700]
|
||||
$(@parent).append(@el)
|
||||
|
||||
explode: ->
|
||||
el = $(@el)
|
||||
el.show().animate({opacity: 0.0, top: parseInt(@top + (Math.sin(@dir) * @dst)), left: parseInt(@left + (Math.cos(@dir) * @dst)), rotate: @rot_dist}, @dur, "easeOutCubic", (() -> el.remove()))
|
||||
|
||||
explode_hearts = (@board, @el) ->
|
||||
randomsymbol = -> ['♪','★','✶'][parseInt(Math.random() * 3)]
|
||||
symbol = if Math.random() < 0.3 then randomsymbol() else '♥'
|
||||
parent = @board.el
|
||||
[top, left, height, width] = [@el.top(), @el.left(), @el.height(), @el.width()]
|
||||
hearts = for i in [0..(22 + (6 - Math.floor(Math.random() * 12)))]
|
||||
new Heart(parent, top + (0.5 * height), left + (0.5 * width), symbol)
|
||||
(h.explode() for h in hearts)
|
||||
|
||||
|
||||
# The board is the principle object on which all other objects are
|
||||
# dependent. I decided to make it a 'Dimensioned' because I'm going
|
||||
# to be constantly querying its height and width.
|
||||
|
||||
class Board extends Dimensioned
|
||||
|
||||
append: (ob) -> @el.append(ob)
|
||||
|
||||
css: (width, height) ->
|
||||
@el.css
|
||||
width: width
|
||||
height: height
|
||||
@reset_dims()
|
||||
|
||||
|
||||
|
||||
class Footer extends Dimensioned
|
||||
|
||||
|
||||
|
||||
# A Tile is a word tile. It has a single word.
|
||||
|
||||
class Tile extends Dimensioned
|
||||
|
||||
base_style:
|
||||
'font-size': "15px"
|
||||
|
||||
drag_style:
|
||||
'font-size': "19px"
|
||||
|
||||
visible: false
|
||||
|
||||
# Initial tilt.
|
||||
rotation: (Math.random() * 30) - 15
|
||||
|
||||
constructor: (@word, @board, @master) ->
|
||||
@el = $('<div class="word">' + @word.w + '</div>')
|
||||
@el.css @base_style
|
||||
@board.append(@el)
|
||||
@rotation = (Math.random() * 30) - 15
|
||||
|
||||
@el.draggable
|
||||
helper: "original"
|
||||
refreshPositions: false
|
||||
revertDuration: 1
|
||||
|
||||
start: (event) =>
|
||||
mod = (Math.random() * 16) - 8
|
||||
@rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
|
||||
style = clone(@drag_style)
|
||||
style.rotate = @rotation
|
||||
@el.animate(style, 200, () => @new_width = @el.width())
|
||||
true
|
||||
|
||||
stop: (event) =>
|
||||
# Drop the thing dead center, at least on the x-axis,
|
||||
# and animate its return to the new font size.
|
||||
mod = (Math.random() * 16) - 8
|
||||
@rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
|
||||
style = clone(@base_style)
|
||||
style.rotate = @rotation
|
||||
style['left'] = parseInt(@el.position().left + (0.5 * (@new_width - @width())))
|
||||
@el.animate style, 200, 'easeOutQuad', () =>
|
||||
@reset_dims()
|
||||
explode_hearts(@board, @)
|
||||
@master.poemed(@)
|
||||
true
|
||||
|
||||
fadeOut: -> $.Deferred((d) => @el.fadeOut('fast', (() => @unset_dims(); @visible = false; d.resolve()))).promise()
|
||||
|
||||
# Shape for deteriming poemed collision
|
||||
fuzzyshape: -> shape @left() - WIDTH_FUZZ, @top() - HEIGHT_FUZZ, @width() + (2 * WIDTH_FUZZ), @height() + (2 * HEIGHT_FUZZ)
|
||||
|
||||
get_new_pos: ->
|
||||
bh = => parseInt(Math.random() * (@board.height() - @height()) * 0.985)
|
||||
bw = => parseInt(Math.random() * (@board.width() - @width()) * 0.98)
|
||||
[top, left] = [bh(), bw()]
|
||||
[top, left] = [bh(), bw()] until @master.unoccupied(left, top, @width(), @height())
|
||||
[top, left]
|
||||
|
||||
flyIn: ->
|
||||
fd = (mod) ->
|
||||
m = parseInt(40 * Math.random())
|
||||
if (Math.random() < 0.5) then mod + m else -1 * m
|
||||
@el.css
|
||||
left: fd(@board.width())
|
||||
top: fd(@board.height())
|
||||
dfd = $.Deferred()
|
||||
x = Math.random()
|
||||
[top, left] = @get_new_pos()
|
||||
@el.fadeIn().animate {top: top, left: left, rotate: @rotation}, 1500, 'easeOutQuint', () =>
|
||||
@visible = true
|
||||
dfd.resolve()
|
||||
dfd.promise()
|
||||
|
||||
|
||||
|
||||
class PoemDisplay extends Dimensioned
|
||||
el: $('#results')
|
||||
_max_box: null
|
||||
dialog: $('#message')
|
||||
dtimer: null
|
||||
|
||||
constructor: (@board) ->
|
||||
@el.css({top: @board.height()})
|
||||
|
||||
sentSuccess: (data, textStatus) =>
|
||||
$('p', @dialog).html "Your poem has been immortalized! It can be seen on Twitter at <a href='https://twitter.com/#!/html5magnets'>@html5magnets</a>."
|
||||
if data.error
|
||||
$('p', @dialog).html data.message
|
||||
|
||||
@dialog.dialog("open")
|
||||
if dtimer != null
|
||||
clearTimeout(dtimer)
|
||||
dtimer = null
|
||||
dtimer = setTimeout (() => @dialog.dialog("close")), 7500
|
||||
|
||||
sentError: (query, textStatus) =>
|
||||
console.log(query, textStatus)
|
||||
|
||||
sendToServer: (haiku) =>
|
||||
$.ajax 'http://html5magnets.elfsternberg.com/poems/',
|
||||
type: "POST"
|
||||
data: {"message": haiku}
|
||||
dataType: 'json'
|
||||
success: @sentSuccess
|
||||
error: @sentError
|
||||
|
||||
update: (lines) ->
|
||||
lines = (l for l in lines when l.length > 0)
|
||||
if lines.length == 0
|
||||
@el.fadeOut()
|
||||
return
|
||||
|
||||
@el.html('')
|
||||
@el.show()
|
||||
res = for words in lines
|
||||
line = words[0].w
|
||||
for word in words[1...words.length]
|
||||
line += if word.s == 1 then word.w else ' ' + word.w
|
||||
@el.append($('<p>' + line + '</p>'))
|
||||
|
||||
sentence = for words in lines
|
||||
line = words[0].w
|
||||
for word in words[1...words.length]
|
||||
line += if word.s == 1 then word.w else ' ' + word.w
|
||||
line
|
||||
|
||||
haiku_add = 0
|
||||
if sentence.length > 1
|
||||
haiku = sentence.join(" / ")
|
||||
if haiku.length < 140
|
||||
haiku_add = 38
|
||||
@el.append('<div id="tweetthis"><img src="tweetthis.png"></div>')
|
||||
$('#tweetthis').click(() => @sendToServer(lines))
|
||||
|
||||
if lines.length != @lastlines
|
||||
lh = $('p', @el).height()
|
||||
setTimeout((() => @el.animate {top: @board.height() - ((lh * (lines.length + 1.7)) + haiku_add)}), 1)
|
||||
@
|
||||
|
||||
max_box: =>
|
||||
return shape(@board.height() - (16 * 6.7), 0, 480, (16 * 6.7))
|
||||
|
||||
|
||||
# A poem is three or more *moved* words in fuzzy collision.
|
||||
|
||||
class Poem
|
||||
words: []
|
||||
|
||||
constructor: (@master) ->
|
||||
@poembox = new PoemDisplay(@master.board)
|
||||
|
||||
real_poem: (poem = null) ->
|
||||
poem = @words if not poem?
|
||||
if poem.length > 1 then poem else []
|
||||
|
||||
has: (word) ->
|
||||
return (w for w in @words when w == word).length > 0
|
||||
|
||||
find_bbox: (words = null, sp = 0) ->
|
||||
words = @words if not words
|
||||
return null if words.length < 2
|
||||
[ul, ur, lr, ll] = words[0].shape()
|
||||
[mx, my, nx, ny] = [ul.x, ul.y, lr.x, lr.y]
|
||||
for i in [1...words.length]
|
||||
[ul1, ur1, lr1, ll1] = words[i].shape()
|
||||
mx = ul1.x if ul1.x < mx
|
||||
my = ul1.y if ul1.y < my
|
||||
nx = lr1.x if lr1.x > nx
|
||||
ny = lr1.y if lr1.y > ny
|
||||
return [{x: mx - sp, y: my - sp}, {x: nx + sp, y: my - sp}, {x: nx + sp, y: ny + sp}, {x: nx + sp, y: my - sp}]
|
||||
|
||||
check_dismissal: (word) ->
|
||||
# If the word is colliding with another word in the poem, it
|
||||
# is not being dismissed.
|
||||
fuzzyshape = word.fuzzyshape()
|
||||
for w in @words
|
||||
if w != word and colliding(fuzzyshape, w.fuzzyshape())
|
||||
@inorder()
|
||||
return @words
|
||||
|
||||
# Remove word from @words
|
||||
@words = @real_poem(w for w in @words when w != word)
|
||||
return @words if @words.length < 2
|
||||
|
||||
# Reconstitute poem from what remains
|
||||
find_split_poem = (poem) =>
|
||||
# Why 2? Because a poem of length 1 is just a word!
|
||||
throw "Don't run on an empty poem!" if poem.length < 2
|
||||
|
||||
# Transfer all words in *poem2* that are in collision with
|
||||
# words in poem1. If the poems don't change, return them,
|
||||
# otherwise repeat the process.
|
||||
|
||||
edgefollow = (poem1, poem2) =>
|
||||
to_xfr = (w2 for w2 in poem2 when \
|
||||
((w1 for w1 in poem1 when \
|
||||
colliding(w1.fuzzyshape(), w2.fuzzyshape())).length > 0))
|
||||
|
||||
# Words are not being shuffled around
|
||||
return [poem1, poem2] if to_xfr.length == 0
|
||||
|
||||
# Else...
|
||||
poem1 = poem1.concat(to_xfr)
|
||||
poem2 = (w for w in poem2 when w not in poem1)
|
||||
edgefollow(poem1, poem2)
|
||||
|
||||
wordlist = (i for i in poem)
|
||||
first_word = wordlist.pop()
|
||||
[lpoem, rpoem] = edgefollow([first_word], wordlist)
|
||||
return [] if lpoem.length < 2 and lpoem.length < 2
|
||||
return rpoem if lpoem.length < 2
|
||||
return lpoem if rpoem.length < 2
|
||||
return if Math.vector.magnitude(@find_bbox(lpoem)[0]) < Math.vector.magnitude(@find_bbox(rpoem)[0])
|
||||
lpoem
|
||||
else
|
||||
rpoem
|
||||
|
||||
@words = @real_poem(find_split_poem(@words))
|
||||
if @words
|
||||
@inorder()
|
||||
@words
|
||||
|
||||
# Looks at the bounding box for the current poem and adds any words
|
||||
# to it that are in collision with the existing poem.
|
||||
# :: [tiles] -> [tiles]
|
||||
|
||||
research_poem: (poem) ->
|
||||
nbbox = @find_bbox(poem)
|
||||
newpoem = (i for i in poem)
|
||||
potentials = (w for w in @master.visible() when \
|
||||
(w not in newpoem) and colliding(w.fuzzyshape(), nbbox))
|
||||
|
||||
# [word, poem] -> boolean
|
||||
collides_with_existing_poem = (nw1, poem1) ->
|
||||
fzs1 = nw1.fuzzyshape()
|
||||
acw1 = nw1.word
|
||||
((nw2 for nw2 in poem1 when \
|
||||
acw1 != nw2.word and \
|
||||
colliding(nw2.fuzzyshape(), fzs1)).length > 0)
|
||||
|
||||
addenda = (nw for nw in potentials when collides_with_existing_poem(nw, newpoem))
|
||||
if addenda.length == 0 then newpoem else @research_poem(newpoem.concat(addenda))
|
||||
|
||||
|
||||
# Looks to see if the word has come into collision with another
|
||||
# word, creating a new poem.
|
||||
# :: tile -> [tiles]
|
||||
|
||||
maybe_new_poem: (word) ->
|
||||
throw "Do not call maybe_new_poem on a working poem." if @words.length > 0
|
||||
|
||||
fuzzyshape = word.fuzzyshape()
|
||||
@words = @real_poem((w for w in @master.visible() when \
|
||||
colliding(w.fuzzyshape(), fuzzyshape)))
|
||||
|
||||
if @words.length
|
||||
@words = @research_poem(@words)
|
||||
|
||||
@inorder()
|
||||
@words
|
||||
|
||||
|
||||
check_for_addition: (word) ->
|
||||
# See if this word collides with any of the words in our poem:
|
||||
fuzzyshape = word.fuzzyshape()
|
||||
for w in @words
|
||||
if colliding(fuzzyshape, w.fuzzyshape()) and w != word
|
||||
@words.push(word)
|
||||
# One collision is all it takes.
|
||||
break
|
||||
|
||||
@words = @research_poem(@words)
|
||||
@inorder()
|
||||
@words
|
||||
|
||||
|
||||
check: (word) ->
|
||||
return @words = @maybe_new_poem(word) if @words.length == 0
|
||||
|
||||
if @has(word)
|
||||
@words = @check_dismissal(word)
|
||||
return @words = if @words.length == 0 then @maybe_new_poem(word) else @words
|
||||
|
||||
# This word doesn't create a new poem, and it isn't present in
|
||||
# our existing poem.
|
||||
|
||||
return @words = @check_for_addition(word)
|
||||
|
||||
|
||||
inorder: ->
|
||||
return @poembox.update([]) if @words.length < 2
|
||||
nbbox = @find_bbox(@words)
|
||||
avg_height = 0
|
||||
for w in @words
|
||||
avg_height = avg_height + w.height()
|
||||
avg_height = parseInt(avg_height / @words.length)
|
||||
ret = []
|
||||
for i in (i for i in [nbbox[0].y...nbbox[2].y] by avg_height)
|
||||
zbot = i + avg_height
|
||||
zone_words = (w for w in @words when w.top() >= i and w.top() < zbot)
|
||||
zone_words.sort (a, b) -> a.left() - b.left()
|
||||
ret.push((i.word for i in zone_words))
|
||||
@poembox.update(ret)
|
||||
|
||||
|
||||
|
||||
class Magnets extends Dimensioned
|
||||
|
||||
constructor: (@wordlist) ->
|
||||
@el = $(window)
|
||||
@footer = new Footer($('#footer'))
|
||||
@board = new Board($('#board'))
|
||||
@recbox = $('#recbox')
|
||||
@results = $('#results')
|
||||
@words = (new Tile(word, @board, @) for word in @wordlist)
|
||||
@resize()
|
||||
@poem = new Poem(@)
|
||||
$('#shuffler').click(@reword)
|
||||
$(window).resize(@resize)
|
||||
|
||||
resize: =>
|
||||
@unset_dims()
|
||||
@board.css('100%', @height() - @footer.height())
|
||||
(word.visibleReposition() for word in @words when word.visible)
|
||||
@
|
||||
|
||||
unoccupied:(left, top, width, height) ->
|
||||
reserved = []
|
||||
if @poem.real_poem().length > 0
|
||||
reserved.push(@poem.find_bbox(null, 10))
|
||||
reserved.push(@poem.poembox.max_box())
|
||||
target = shape(left, top, width, height)
|
||||
for s in reserved
|
||||
if colliding(target, s)
|
||||
return false
|
||||
true
|
||||
|
||||
visible: ->
|
||||
(w for w in @words when w.visible)
|
||||
|
||||
poemed: (word) ->
|
||||
@poem.check(word)
|
||||
|
||||
livewords: -> (w for w in @words when w.visible)
|
||||
|
||||
reword: =>
|
||||
poemed = (w for w in @words when @poem.has(w))
|
||||
flyprob = AVG_VISIBLE / (@words.length - poemed.length)
|
||||
$.when.apply(null, (w.fadeOut() for w in @words when not @poem.has(w))).then () =>
|
||||
$.when.apply(null, (w.flyIn() for w in @words when not @poem.has(w) and Math.random() < flyprob)).then () =>
|
||||
(w.reset_dims() for w in @words when w.visible)
|
||||
@
|
||||
|
||||
|
||||
class MusicPlayer
|
||||
constructor: (control, tunes) ->
|
||||
@control = $(control)
|
||||
@control.data('state', 'on')
|
||||
@active = true
|
||||
@music = new buzz.sound(tunes, {preload:true, autoload: true, loop: true})
|
||||
@music.setVolume(0)
|
||||
@music.bind 'canplaythrough', () =>
|
||||
@music.play()
|
||||
@music.fadeTo(60, 10000)
|
||||
|
||||
@control.click (ev) =>
|
||||
@active = if @active then @fadeOut() else @fadeIn()
|
||||
|
||||
fadeOut: ->
|
||||
@music.fadeOut(600, () => @music.pause())
|
||||
$('img', @control).attr('src', 'mute.png')
|
||||
false
|
||||
|
||||
fadeIn: ->
|
||||
@music.play().fadeIn(1200)
|
||||
$('img', @control).attr('src', 'unmute.png')
|
||||
true
|
||||
|
||||
|
||||
$ ->
|
||||
$.ajax
|
||||
url: 'js/wordlist.js'
|
||||
data: {}
|
||||
success: (data) -> (new Magnets(data)).resize().reword()
|
||||
error: -> console.log(arguments)
|
||||
dataType: 'json'
|
||||
|
||||
v = new MusicPlayer('#muteunmute',
|
||||
['media/snowflake_-_Ethereal_Space.mp3',
|
||||
'media/snowflake_-_Ethereal_Space.ogg'])
|
||||
|
||||
$( "#message" ).dialog
|
||||
autoOpen: false
|
||||
show: "fadeIn"
|
||||
hide: "fadeOut"
|
|
@ -0,0 +1,97 @@
|
|||
#Copyright (c) 2012 Elf M. Sternberg
|
||||
#
|
||||
# Much of the code here I would never have understood if it hadn't
|
||||
# been for the patient work of Caleb Helbling
|
||||
# (http://www.propulsionjs.com/), as well as the Wikipedia pages for
|
||||
# the Separating Axis Theorem. It took me a week to wrap my head
|
||||
# around these ideas.
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
#of this software and associated documentation files (the "Software"), to deal
|
||||
#in the Software without restriction, including without limitation the rights
|
||||
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
#copies of the Software, and to permit persons to whom the Software is
|
||||
#furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in
|
||||
#all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
#THE SOFTWARE.
|
||||
|
||||
Math.vector =
|
||||
add: (v1, v2) -> {x: (v1.x + v2.x), y: (v1.y + v2.y)}
|
||||
|
||||
# Scale a given vector.
|
||||
scalar: (v, s) -> {x: (v.x * s), y: (v.y * s)}
|
||||
|
||||
dot: (v1, v2) -> v1.x * v2.x + v1.y * v2.y
|
||||
|
||||
magnitude2: (v) ->
|
||||
x = v.x
|
||||
y = v.y
|
||||
x * x + y * y
|
||||
|
||||
magnitude: (v) -> Math.sqrt(Math.vector.magnitude2(v))
|
||||
|
||||
normalize: (v) ->
|
||||
mag = Math.vector.magnitude(v)
|
||||
{x: (v.x / mag), y: (v.y / mag)}
|
||||
|
||||
leftNormal: (v) -> {x: -v.y, y: v.x}
|
||||
|
||||
|
||||
|
||||
this.colliding = (shape1, shape2) ->
|
||||
|
||||
# Return the axes of a shape. In a polygon, each potential
|
||||
# separating axis is the normal to each edge. For our purposes, a
|
||||
# "shape" is an array of points with the structure [{x: 0, y: 0}, .. ]
|
||||
# We assume that the final edge is from the last point back to the
|
||||
# first.
|
||||
|
||||
genAxes = (shape) ->
|
||||
throw "Cannot handle non-polygons" if shape.length < 3
|
||||
|
||||
# Calculate the normal of a single pair of points in the
|
||||
# shape.
|
||||
|
||||
axis = (shape, pi) ->
|
||||
p1 = shape[pi]
|
||||
p2 = shape[if pi == (shape.length - 1) then 0 else pi + 1]
|
||||
edge = {x: p1.x - p2.x, y: p1.y - p2.y}
|
||||
Math.vector.normalize(Math.vector.leftNormal(edge))
|
||||
|
||||
(axis(shape, i) for i in [0...shape.length])
|
||||
|
||||
# Calculate the extremis of the shape "above" a given axis
|
||||
|
||||
genProjection = (shape, axis) ->
|
||||
min = Math.vector.dot(axis, shape[0])
|
||||
max = min
|
||||
for i in [1...shape.length]
|
||||
p = Math.vector.dot(axis, shape[i])
|
||||
min = p if p < min
|
||||
max = p if p > max
|
||||
{min: min, max: max}
|
||||
|
||||
axes1 = genAxes(shape1)
|
||||
axes2 = genAxes(shape2)
|
||||
axes = axes1.concat axes2
|
||||
for axis in axes
|
||||
proj1 = genProjection(shape1, axis)
|
||||
proj2 = genProjection(shape2, axis)
|
||||
if not ( \
|
||||
(proj1.min >= proj2.min and proj1.min <= proj2.max) or \
|
||||
(proj1.max >= proj2.min and proj1.max <= proj2.max) or \
|
||||
(proj2.min >= proj1.min and proj2.min <= proj1.max) or \
|
||||
(proj2.max >= proj1.min and proj2.max <= proj1.max))
|
||||
return false
|
||||
return true
|
||||
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
/* -*- mode: css; -*- */
|
||||
|
||||
/* ___ ___ ___ ___ _
|
||||
/ __/ __/ __| | _ \___ ___ ___| |_
|
||||
| (__\__ \__ \ | / -_|_-</ -_) _|
|
||||
\___|___/___/ |_|_\___/__/\___|\__|
|
||||
|
||||
html5doctor.com Reset Stylesheet
|
||||
v1.5
|
||||
Last Updated: 2010-08-12
|
||||
Author: Richard Clark - http://richclarkdesign.com
|
||||
Twitter: @rich_clark
|
||||
*/
|
||||
|
||||
html, body, div, span, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
abbr, address, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, samp,
|
||||
small, strong, sub, sup, var,
|
||||
b, i,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin:0;
|
||||
padding:0;
|
||||
border:0;
|
||||
outline:0;
|
||||
vertical-align:baseline;
|
||||
background:transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height:1;
|
||||
}
|
||||
|
||||
article,aside,canvas,details,figcaption,figure,
|
||||
footer,header,hgroup,menu,nav,section,summary {
|
||||
display:block;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
blockquote, q {
|
||||
quotes:none;
|
||||
}
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content:'';
|
||||
content:none;
|
||||
}
|
||||
|
||||
a {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-size:100%;
|
||||
vertical-align:baseline;
|
||||
background:transparent;
|
||||
}
|
||||
|
||||
a {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-size:100%;
|
||||
vertical-align:baseline;
|
||||
background:transparent;
|
||||
}
|
||||
|
||||
ins {
|
||||
background-color:#ff9;
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color:#ff9;
|
||||
color:#000;
|
||||
font-style:italic;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
abbr[title], dfn[title] {
|
||||
border-bottom:1px dotted #000;
|
||||
cursor:help;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
border-spacing:0;
|
||||
}
|
||||
|
||||
hr {
|
||||
display:block;
|
||||
height:1px;
|
||||
border:0;
|
||||
border-top:1px solid #cccccc;
|
||||
margin:1em 0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
input, select {
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.small-rounded {
|
||||
-moz-border-radius-topleft: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
-moz-border-radius-bottomleft: 5px;
|
||||
-moz-border-radius-bottomright: 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@limegreen: #32cd32;
|
||||
|
||||
#board {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: url('pingbg.png') repeat;
|
||||
}
|
||||
|
||||
.word {
|
||||
font-family: Georgia, Palatino,"Palatino Linotype", Times, "Times New Roman", serif;
|
||||
-moz-box-shadow: 0 0 6px 2px #aaa;
|
||||
-webkit-box-shadow: 0 0 6px 2px #aaa;
|
||||
box-shadow: 0 0 6px 2px #aaa;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
color: #444;
|
||||
font-size: 13px;
|
||||
padding: 3px 4px 4px 4px;
|
||||
position: absolute;
|
||||
background: white;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
|
||||
#footer {
|
||||
height: 18ex;
|
||||
font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande", "Lucida Sans", Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#stripe {
|
||||
width: 100%;
|
||||
margin: 0.4% 0 0.4% 0;
|
||||
background-color: @limegreen;
|
||||
height: 10ex;
|
||||
}
|
||||
|
||||
.heart {
|
||||
position: absolute;
|
||||
color: deeppink;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
z-index: 30;
|
||||
}
|
||||
|
||||
#f1 { width: 46%; float: left; padding-left: 1%;}
|
||||
#f2 { width: 46%; float: right; text-align: right; padding-right: 1%;}
|
||||
|
||||
.recline {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
clear: right;
|
||||
background: url(writerect_bg.png) top left repeat-x;
|
||||
}
|
||||
|
||||
#results {
|
||||
-moz-border-radius-topright: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
border-top: 1px solid #888;
|
||||
border-right: 1px solid #888;
|
||||
border-bottom: 1px solid #888;
|
||||
position: absolute;
|
||||
color: #666;
|
||||
left: 0px;
|
||||
bottom: 5px;
|
||||
padding: 1em;
|
||||
background: url(alphamod.png) repeat;
|
||||
display: none;
|
||||
|
||||
p {
|
||||
white-space: nowrap;
|
||||
line-height: 1.1;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#shuffler {
|
||||
font-family: Georgia, Palatino,"Palatino Linotype", Times, "Times New Roman", serif;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
position: relative;
|
||||
background-color: @limegreen;
|
||||
margin-top: 10px;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
margin-right: 32px;
|
||||
width: 5em;
|
||||
vertical-align: middle;
|
||||
border-top: 1px solid white;
|
||||
border-left: 1px solid white;
|
||||
border-bottom: 1px solid black;
|
||||
border-right: 1px solid black;
|
||||
box-shadow: 1px 3px 6px rgba(0, 0, 0, 0.80);
|
||||
-moz-box-shadow: 1px 3px 6px rgba(0, 0, 0, 0.80);
|
||||
-webkit-box-shadow: 1px 3px 6px rgba(0, 0, 0, 0.80);
|
||||
}
|
||||
|
||||
#shuffler:hover {
|
||||
background-color: darken(@limegreen, 10%);
|
||||
}
|
||||
|
||||
#shuffler:active {
|
||||
background-color: darken(@limegreen, 10%);
|
||||
border-top: 1px solid black;
|
||||
border-left: 1px solid black;
|
||||
border-bottom: 1px solid white;
|
||||
border-right: 1px solid white;
|
||||
}
|
||||
|
||||
#muteunmute {
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
padding-right: 128px;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
|
||||
img {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
#tweetthis {
|
||||
padding-top: 6px;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
testCase = require('nodeunit').testCase
|
||||
require('./sat.coffee')
|
||||
|
||||
module.exports = testCase
|
||||
"TestAddition": (test) ->
|
||||
m = Math.vector.add {x: 1, y: 1}, {x: -1, y: -1}
|
||||
test.ok(m.x == 0 and m.y == 0)
|
||||
m = Math.vector.add {x: 1, y: 1}, {x: 1, y: 1}
|
||||
test.ok(m.x == 2 and m.y == 2)
|
||||
test.done()
|
||||
|
||||
"TestScalar": (test) ->
|
||||
m = Math.vector.scalar({x: 2, y: 2}, 2)
|
||||
test.ok(m.x == 4 and m.y == 4)
|
||||
test.done()
|
||||
|
||||
"TestMag2": (test) ->
|
||||
m = Math.vector.magnitude2({x: 2, y: 2})
|
||||
test.ok(m == 8)
|
||||
test.done()
|
||||
|
||||
"TestMag": (test) ->
|
||||
m = Math.vector.magnitude({x: 2, y: 2})
|
||||
test.ok(m == Math.sqrt(8))
|
||||
test.done()
|
||||
|
||||
"TestNormalize": (test) ->
|
||||
m = Math.vector.normalize({x: 5, y: 0})
|
||||
test.ok(m.x == 1 and m.y == 0)
|
||||
m = Math.vector.normalize({x: 0, y: 5})
|
||||
test.ok(m.x == 0 and m.y == 1)
|
||||
m = Math.vector.normalize({x: 4, y: 3})
|
||||
test.ok((m.x * m.x + m.y * m.y) == 1)
|
||||
test.done()
|
|
@ -0,0 +1,210 @@
|
|||
[{"w": "a", "s": 0},
|
||||
{"w": "a", "s": 0},
|
||||
{"w": "about", "s": 0},
|
||||
{"w": "above", "s": 0},
|
||||
{"w": "after", "s": 0},
|
||||
{"w": "all", "s": 0},
|
||||
{"w": "almost", "s": 0},
|
||||
{"w": "always", "s": 0},
|
||||
{"w": "am", "s": 0},
|
||||
{"w": "an", "s": 0},
|
||||
{"w": "an", "s": 0},
|
||||
{"w": "and", "s": 0},
|
||||
{"w": "and", "s": 0},
|
||||
{"w": "animal", "s": 0},
|
||||
{"w": "apple", "s": 0},
|
||||
{"w": "are", "s": 0},
|
||||
{"w": "as", "s": 0},
|
||||
{"w": "as", "s": 0},
|
||||
{"w": "ask", "s": 0},
|
||||
{"w": "at", "s": 0},
|
||||
{"w": "bad", "s": 0},
|
||||
{"w": "be", "s": 0},
|
||||
{"w": "beauty", "s": 0},
|
||||
{"w": "believe", "s": 0},
|
||||
{"w": "beneath", "s": 0},
|
||||
{"w": "between", "s": 0},
|
||||
{"w": "bird", "s": 0},
|
||||
{"w": "birthday", "s": 0},
|
||||
{"w": "blend", "s": 0},
|
||||
{"w": "blue", "s": 0},
|
||||
{"w": "bring", "s": 0},
|
||||
{"w": "but", "s": 0},
|
||||
{"w": "but", "s": 0},
|
||||
{"w": "butterfly", "s": 0},
|
||||
{"w": "by", "s": 0},
|
||||
{"w": "calendar", "s": 0},
|
||||
{"w": "can", "s": 0},
|
||||
{"w": "celebrate", "s": 0},
|
||||
{"w": "change", "s": 0},
|
||||
{"w": "cloud", "s": 0},
|
||||
{"w": "cold", "s": 0},
|
||||
{"w": "come", "s": 0},
|
||||
{"w": "comfort", "s": 0},
|
||||
{"w": "could", "s": 0},
|
||||
{"w": "d", "s": 1},
|
||||
{"w": "dark", "s": 0},
|
||||
{"w": "day", "s": 0},
|
||||
{"w": "delightful", "s": 0},
|
||||
{"w": "desire", "s": 0},
|
||||
{"w": "did", "s": 0},
|
||||
{"w": "do", "s": 0},
|
||||
{"w": "dream", "s": 0},
|
||||
{"w": "e", "s": 1},
|
||||
{"w": "eat", "s": 0},
|
||||
{"w": "ed", "s": 1},
|
||||
{"w": "er", "s": 1},
|
||||
{"w": "es", "s": 1},
|
||||
{"w": "est", "s": 1},
|
||||
{"w": "evening", "s": 0},
|
||||
{"w": "every", "s": 0},
|
||||
{"w": "fall", "s": 0},
|
||||
{"w": "favorite", "s": 0},
|
||||
{"w": "feel", "s": 0},
|
||||
{"w": "float", "s": 0},
|
||||
{"w": "flower", "s": 0},
|
||||
{"w": "for", "s": 0},
|
||||
{"w": "from", "s": 0},
|
||||
{"w": "full", "s": 0},
|
||||
{"w": "fun", "s": 0},
|
||||
{"w": "garden", "s": 0},
|
||||
{"w": "get", "s": 0},
|
||||
{"w": "ghost", "s": 0},
|
||||
{"w": "good", "s": 0},
|
||||
{"w": "grass", "s": 0},
|
||||
{"w": "green", "s": 0},
|
||||
{"w": "grow", "s": 0},
|
||||
{"w": "happy", "s": 0},
|
||||
{"w": "has", "s": 0},
|
||||
{"w": "have", "s": 0},
|
||||
{"w": "he", "s": 0},
|
||||
{"w": "here", "s": 0},
|
||||
{"w": "here", "s": 0},
|
||||
{"w": "him", "s": 0},
|
||||
{"w": "his", "s": 0},
|
||||
{"w": "hot", "s": 0},
|
||||
{"w": "house", "s": 0},
|
||||
{"w": "how", "s": 0},
|
||||
{"w": "I", "s": 0},
|
||||
{"w": "I", "s": 0},
|
||||
{"w": "if", "s": 0},
|
||||
{"w": "in", "s": 0},
|
||||
{"w": "ing", "s": 1},
|
||||
{"w": "ing", "s": 1},
|
||||
{"w": "is", "s": 0},
|
||||
{"w": "is", "s": 0},
|
||||
{"w": "it", "s": 0},
|
||||
{"w": "keep", "s": 0},
|
||||
{"w": "laugh", "s": 0},
|
||||
{"w": "learn", "s": 0},
|
||||
{"w": "leave", "s": 0},
|
||||
{"w": "let", "s": 0},
|
||||
{"w": "light", "s": 0},
|
||||
{"w": "like", "s": 0},
|
||||
{"w": "like", "s": 0},
|
||||
{"w": "live", "s": 0},
|
||||
{"w": "long", "s": 0},
|
||||
{"w": "look", "s": 0},
|
||||
{"w": "love", "s": 0},
|
||||
{"w": "ly", "s": 1},
|
||||
{"w": "magic", "s": 0},
|
||||
{"w": "make", "s": 0},
|
||||
{"w": "man", "s": 0},
|
||||
{"w": "me", "s": 0},
|
||||
{"w": "memory", "s": 0},
|
||||
{"w": "month", "s": 0},
|
||||
{"w": "more", "s": 0},
|
||||
{"w": "morning", "s": 0},
|
||||
{"w": "must", "s": 0},
|
||||
{"w": "my", "s": 0},
|
||||
{"w": "never", "s": 0},
|
||||
{"w": "nibble", "s": 0},
|
||||
{"w": "night", "s": 0},
|
||||
{"w": "no", "s": 0},
|
||||
{"w": "of", "s": 0},
|
||||
{"w": "of", "s": 0},
|
||||
{"w": "off", "s": 0},
|
||||
{"w": "on", "s": 0},
|
||||
{"w": "only", "s": 0},
|
||||
{"w": "or", "s": 0},
|
||||
{"w": "out", "s": 0},
|
||||
{"w": "out", "s": 0},
|
||||
{"w": "paint", "s": 0},
|
||||
{"w": "people", "s": 0},
|
||||
{"w": "perfect", "s": 0},
|
||||
{"w": "play", "s": 0},
|
||||
{"w": "proof", "s": 0},
|
||||
{"w": "puff", "s": 0},
|
||||
{"w": "r", "s": 1},
|
||||
{"w": "rain", "s": 0},
|
||||
{"w": "room", "s": 0},
|
||||
{"w": "s", "s": 1},
|
||||
{"w": "s", "s": 1},
|
||||
{"w": "s", "s": 1},
|
||||
{"w": "say", "s": 0},
|
||||
{"w": "season", "s": 0},
|
||||
{"w": "see", "s": 0},
|
||||
{"w": "she", "s": 0},
|
||||
{"w": "shine", "s": 0},
|
||||
{"w": "simple", "s": 0},
|
||||
{"w": "sky", "s": 0},
|
||||
{"w": "snow", "s": 0},
|
||||
{"w": "so", "s": 0},
|
||||
{"w": "some", "s": 0},
|
||||
{"w": "song", "s": 0},
|
||||
{"w": "spring", "s": 0},
|
||||
{"w": "summer", "s": 0},
|
||||
{"w": "sun", "s": 0},
|
||||
{"w": "sweet", "s": 0},
|
||||
{"w": "take", "s": 0},
|
||||
{"w": "talk", "s": 0},
|
||||
{"w": "than", "s": 0},
|
||||
{"w": "that", "s": 0},
|
||||
{"w": "the", "s": 0},
|
||||
{"w": "the", "s": 0},
|
||||
{"w": "their", "s": 0},
|
||||
{"w": "then", "s": 0},
|
||||
{"w": "there", "s": 0},
|
||||
{"w": "they", "s": 0},
|
||||
{"w": "this", "s": 0},
|
||||
{"w": "though", "s": 0},
|
||||
{"w": "through", "s": 0},
|
||||
{"w": "time", "s": 0},
|
||||
{"w": "to", "s": 0},
|
||||
{"w": "to", "s": 0},
|
||||
{"w": "together", "s": 0},
|
||||
{"w": "too", "s": 0},
|
||||
{"w": "touch", "s": 0},
|
||||
{"w": "trick", "s": 0},
|
||||
{"w": "truth", "s": 0},
|
||||
{"w": "up", "s": 0},
|
||||
{"w": "us", "s": 0},
|
||||
{"w": "use", "s": 0},
|
||||
{"w": "vacation", "s": 0},
|
||||
{"w": "walk", "s": 0},
|
||||
{"w": "want", "s": 0},
|
||||
{"w": "warm", "s": 0},
|
||||
{"w": "was", "s": 0},
|
||||
{"w": "watch", "s": 0},
|
||||
{"w": "we", "s": 0},
|
||||
{"w": "weather", "s": 0},
|
||||
{"w": "were", "s": 0},
|
||||
{"w": "when", "s": 0},
|
||||
{"w": "which", "s": 0},
|
||||
{"w": "whisper", "s": 0},
|
||||
{"w": "who", "s": 0},
|
||||
{"w": "why", "s": 0},
|
||||
{"w": "will", "s": 0},
|
||||
{"w": "winter", "s": 0},
|
||||
{"w": "with", "s": 0},
|
||||
{"w": "woman", "s": 0},
|
||||
{"w": "word", "s": 0},
|
||||
{"w": "work", "s": 0},
|
||||
{"w": "world", "s": 0},
|
||||
{"w": "would", "s": 0},
|
||||
{"w": "y", "s": 1},
|
||||
{"w": "year", "s": 0},
|
||||
{"w": "you", "s": 0},
|
||||
{"w": "you", "s": 0},
|
||||
{"w": "your", "s": 0}
|
||||
]
|
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 104 B |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 105 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 90 B |
After Width: | Height: | Size: 129 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* jQuery UI CSS Framework 1.8.18
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*/
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
|
||||
.ui-helper-clearfix:after { clear: both; }
|
||||
.ui-helper-clearfix { zoom: 1; }
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
|
||||
/*
|
||||
* jQuery UI CSS Framework 1.8.18
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
|
||||
*/
|
||||
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
|
||||
.ui-widget .ui-widget { font-size: 1em; }
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
|
||||
.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
|
||||
.ui-widget-content a { color: #333333; }
|
||||
.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
|
||||
.ui-widget-header a { color: #ffffff; }
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
|
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
|
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
|
||||
.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
|
||||
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
|
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
|
||||
.ui-widget :active { outline: none; }
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
|
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
|
||||
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
|
||||
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
|
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
|
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
|
||||
.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
|
||||
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-off { background-position: -96px -144px; }
|
||||
.ui-icon-radio-on { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
|
||||
.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
|
||||
* jQuery UI Resizable 1.8.18
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Resizable#theming
|
||||
*/
|
||||
.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; }
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
|
||||
* jQuery UI Dialog 1.8.18
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Dialog#theming
|
||||
*/
|
||||
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
||||
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
||||
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
||||
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
After Width: | Height: | Size: 714 B |