* text=auto |
*.wav | *.wav |
*.pyc | *.pyc |
/nbproject/private/ | /nbproject/private/ |
/output.txt | |
bin | |
gen | |
target | |
.settings | |
.classpath | |
.project | |
*.keystore | |
*.swp | |
*.orig | |
*.log | |
*.properties | |
seed.txt | |
map.txt | |
[submodule "pynma"] | [submodule "pynma"] |
path = pynma | path = pynma |
url = git://github.com/uskr/pynma.git | url = git://github.com/uskr/pynma.git |
[submodule "js/flotr2"] | |
path = js/flotr2 | |
url = https://github.com/HumbleSoftware/Flotr2.git | |
# Apache configuration file | |
# httpd.apache.org/docs/2.2/mod/quickreference.html | |
# Note .htaccess files are an overhead, this logic should be in your Apache | |
# config if possible: httpd.apache.org/docs/2.2/howto/htaccess.html | |
# Techniques in here adapted from all over, including: | |
# Kroc Camen: camendesign.com/.htaccess | |
# perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/ | |
# Sample .htaccess file of CMS MODx: modxcms.com | |
# ---------------------------------------------------------------------- | |
# Better website experience for IE users | |
# ---------------------------------------------------------------------- | |
# Force the latest IE version, in various cases when it may fall back to IE7 mode | |
# github.com/rails/rails/commit/123eb25#commitcomment-118920 | |
# Use ChromeFrame if it's installed for a better experience for the poor IE folk | |
<IfModule mod_headers.c> | |
Header set X-UA-Compatible "IE=Edge,chrome=1" | |
# mod_headers can't match by content-type, but we don't want to send this header on *everything*... | |
<FilesMatch "\.(js|css|gif|png|jpe?g|pdf|xml|oga|ogg|m4a|ogv|mp4|m4v|webm|svg|svgz|eot|ttf|otf|woff|ico|webp|appcache|manifest|htc|crx|oex|xpi|safariextz|vcf)$" > | |
Header unset X-UA-Compatible | |
</FilesMatch> | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Cross-domain AJAX requests | |
# ---------------------------------------------------------------------- | |
# Serve cross-domain Ajax requests, disabled by default. | |
# enable-cors.org | |
# code.google.com/p/html5security/wiki/CrossOriginRequestSecurity | |
# <IfModule mod_headers.c> | |
# Header set Access-Control-Allow-Origin "*" | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# CORS-enabled images (@crossorigin) | |
# ---------------------------------------------------------------------- | |
# Send CORS headers if browsers request them; enabled by default for images. | |
# developer.mozilla.org/en/CORS_Enabled_Image | |
# blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html | |
# hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/ | |
# wiki.mozilla.org/Security/Reviews/crossoriginAttribute | |
<IfModule mod_setenvif.c> | |
<IfModule mod_headers.c> | |
# mod_headers, y u no match by Content-Type?! | |
<FilesMatch "\.(gif|png|jpe?g|svg|svgz|ico|webp)$"> | |
SetEnvIf Origin ":" IS_CORS | |
Header set Access-Control-Allow-Origin "*" env=IS_CORS | |
</FilesMatch> | |
</IfModule> | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Webfont access | |
# ---------------------------------------------------------------------- | |
# Allow access from all domains for webfonts. | |
# Alternatively you could only whitelist your | |
# subdomains like "subdomain.example.com". | |
<IfModule mod_headers.c> | |
<FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css)$"> | |
Header set Access-Control-Allow-Origin "*" | |
</FilesMatch> | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Proper MIME type for all files | |
# ---------------------------------------------------------------------- | |
# JavaScript | |
# Normalize to standard type (it's sniffed in IE anyways) | |
# tools.ietf.org/html/rfc4329#section-7.2 | |
AddType application/javascript js jsonp | |
AddType application/json json | |
# Audio | |
AddType audio/ogg oga ogg | |
AddType audio/mp4 m4a f4a f4b | |
# Video | |
AddType video/ogg ogv | |
AddType video/mp4 mp4 m4v f4v f4p | |
AddType video/webm webm | |
AddType video/x-flv flv | |
# SVG | |
# Required for svg webfonts on iPad | |
# twitter.com/FontSquirrel/status/14855840545 | |
AddType image/svg+xml svg svgz | |
AddEncoding gzip svgz | |
# Webfonts | |
AddType application/vnd.ms-fontobject eot | |
AddType application/x-font-ttf ttf ttc | |
AddType font/opentype otf | |
AddType application/x-font-woff woff | |
# Assorted types | |
AddType image/x-icon ico | |
AddType image/webp webp | |
AddType text/cache-manifest appcache manifest | |
AddType text/x-component htc | |
AddType application/xml rss atom xml rdf | |
AddType application/x-chrome-extension crx | |
AddType application/x-opera-extension oex | |
AddType application/x-xpinstall xpi | |
AddType application/octet-stream safariextz | |
AddType application/x-web-app-manifest+json webapp | |
AddType text/x-vcard vcf | |
AddType application/x-shockwave-flash swf | |
AddType text/vtt vtt | |
# ---------------------------------------------------------------------- | |
# Allow concatenation from within specific js and css files | |
# ---------------------------------------------------------------------- | |
# e.g. Inside of script.combined.js you could have | |
# <!--#include file="libs/jquery-1.5.0.min.js" --> | |
# <!--#include file="plugins/jquery.idletimer.js" --> | |
# and they would be included into this single file. | |
# This is not in use in the boilerplate as it stands. You may | |
# choose to use this technique if you do not have a build process. | |
#<FilesMatch "\.combined\.js$"> | |
# Options +Includes | |
# AddOutputFilterByType INCLUDES application/javascript application/json | |
# SetOutputFilter INCLUDES | |
#</FilesMatch> | |
#<FilesMatch "\.combined\.css$"> | |
# Options +Includes | |
# AddOutputFilterByType INCLUDES text/css | |
# SetOutputFilter INCLUDES | |
#</FilesMatch> | |
# ---------------------------------------------------------------------- | |
# Gzip compression | |
# ---------------------------------------------------------------------- | |
<IfModule mod_deflate.c> | |
# Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/ | |
<IfModule mod_setenvif.c> | |
<IfModule mod_headers.c> | |
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding | |
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding | |
</IfModule> | |
</IfModule> | |
# Compress all output labeled with one of the following MIME-types | |
<IfModule mod_filter.c> | |
AddOutputFilterByType DEFLATE application/atom+xml \ | |
application/javascript \ | |
application/json \ | |
application/rss+xml \ | |
application/vnd.ms-fontobject \ | |
application/x-font-ttf \ | |
application/xhtml+xml \ | |
application/xml \ | |
font/opentype \ | |
image/svg+xml \ | |
image/x-icon \ | |
text/css \ | |
text/html \ | |
text/plain \ | |
text/x-component \ | |
text/xml | |
</IfModule> | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Expires headers (for better cache control) | |
# ---------------------------------------------------------------------- | |
# These are pretty far-future expires headers. | |
# They assume you control versioning with filename-based cache busting | |
# Additionally, consider that outdated proxies may miscache | |
# www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/ | |
# If you don't use filenames to version, lower the CSS and JS to something like | |
# "access plus 1 week". | |
<IfModule mod_expires.c> | |
ExpiresActive on | |
# Perhaps better to whitelist expires rules? Perhaps. | |
ExpiresDefault "access plus 1 month" | |
# cache.appcache needs re-requests in FF 3.6 (thanks Remy ~Introducing HTML5) | |
ExpiresByType text/cache-manifest "access plus 0 seconds" | |
# Your document html | |
ExpiresByType text/html "access plus 0 seconds" | |
# Data | |
ExpiresByType text/xml "access plus 0 seconds" | |
ExpiresByType application/xml "access plus 0 seconds" | |
ExpiresByType application/json "access plus 0 seconds" | |
# Feed | |
ExpiresByType application/rss+xml "access plus 1 hour" | |
ExpiresByType application/atom+xml "access plus 1 hour" | |
# Favicon (cannot be renamed) | |
ExpiresByType image/x-icon "access plus 1 week" | |
# Media: images, video, audio | |
ExpiresByType image/gif "access plus 1 month" | |
ExpiresByType image/png "access plus 1 month" | |
ExpiresByType image/jpeg "access plus 1 month" | |
ExpiresByType video/ogg "access plus 1 month" | |
ExpiresByType audio/ogg "access plus 1 month" | |
ExpiresByType video/mp4 "access plus 1 month" | |
ExpiresByType video/webm "access plus 1 month" | |
# HTC files (css3pie) | |
ExpiresByType text/x-component "access plus 1 month" | |
# Webfonts | |
ExpiresByType application/x-font-ttf "access plus 1 month" | |
ExpiresByType font/opentype "access plus 1 month" | |
ExpiresByType application/x-font-woff "access plus 1 month" | |
ExpiresByType image/svg+xml "access plus 1 month" | |
ExpiresByType application/vnd.ms-fontobject "access plus 1 month" | |
# CSS and JavaScript | |
ExpiresByType text/css "access plus 1 year" | |
ExpiresByType application/javascript "access plus 1 year" | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Prevent mobile network providers from modifying your site | |
# ---------------------------------------------------------------------- | |
# The following header prevents modification of your code over 3G on some | |
# European providers. | |
# This is the official 'bypass' suggested by O2 in the UK. | |
# <IfModule mod_headers.c> | |
# Header set Cache-Control "no-transform" | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# ETag removal | |
# ---------------------------------------------------------------------- | |
# FileETag None is not enough for every server. | |
<IfModule mod_headers.c> | |
Header unset ETag | |
</IfModule> | |
# Since we're sending far-future expires, we don't need ETags for | |
# static content. | |
# developer.yahoo.com/performance/rules.html#etags | |
FileETag None | |
# ---------------------------------------------------------------------- | |
# Stop screen flicker in IE on CSS rollovers | |
# ---------------------------------------------------------------------- | |
# The following directives stop screen flicker in IE on CSS rollovers - in | |
# combination with the "ExpiresByType" rules for images (see above). | |
# BrowserMatch "MSIE" brokenvary=1 | |
# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 | |
# BrowserMatch "Opera" !brokenvary | |
# SetEnvIf brokenvary 1 force-no-vary | |
# ---------------------------------------------------------------------- | |
# Set Keep-Alive Header | |
# ---------------------------------------------------------------------- | |
# Keep-Alive allows the server to send multiple requests through one | |
# TCP-connection. Be aware of possible disadvantages of this setting. Turn on | |
# if you serve a lot of static content. | |
# <IfModule mod_headers.c> | |
# Header set Connection Keep-Alive | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# Cookie setting from iframes | |
# ---------------------------------------------------------------------- | |
# Allow cookies to be set from iframes (for IE only) | |
# If needed, specify a path or regex in the Location directive. | |
# <IfModule mod_headers.c> | |
# Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# Start rewrite engine | |
# ---------------------------------------------------------------------- | |
# Turning on the rewrite engine is necessary for the following rules and | |
# features. FollowSymLinks must be enabled for this to work. | |
# Some cloud hosting services require RewriteBase to be set: goo.gl/HOcPN | |
# If using the h5bp in a subdirectory, use `RewriteBase /foo` instead where | |
# 'foo' is your directory. | |
# If your web host doesn't allow the FollowSymlinks option, you may need to | |
# comment it out and use `Options +SymLinksOfOwnerMatch`, but be aware of the | |
# performance impact: http://goo.gl/Mluzd | |
<IfModule mod_rewrite.c> | |
Options +FollowSymlinks | |
# Options +SymLinksIfOwnerMatch | |
RewriteEngine On | |
# RewriteBase / | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Suppress or force the "www." at the beginning of URLs | |
# ---------------------------------------------------------------------- | |
# The same content should never be available under two different URLs - | |
# especially not with and without "www." at the beginning, since this can cause | |
# SEO problems (duplicate content). That's why you should choose one of the | |
# alternatives and redirect the other one. | |
# By default option 1 (no "www.") is activated. | |
# no-www.org/faq.php?q=class_b | |
# If you'd prefer to use option 2, just comment out all option 1 lines | |
# and uncomment option 2. | |
# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME! | |
# ---------------------------------------------------------------------- | |
# Option 1: | |
# Rewrite "www.example.com -> example.com". | |
<IfModule mod_rewrite.c> | |
RewriteCond %{HTTPS} !=on | |
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] | |
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] | |
</IfModule> | |
# ---------------------------------------------------------------------- | |
# Option 2: | |
# Rewrite "example.com -> www.example.com". | |
# Be aware that the following rule might not be a good idea if you use "real" | |
# subdomains for certain parts of your website. | |
# <IfModule mod_rewrite.c> | |
# RewriteCond %{HTTPS} !=on | |
# RewriteCond %{HTTP_HOST} !^www\..+$ [NC] | |
# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# Built-in filename-based cache busting | |
# ---------------------------------------------------------------------- | |
# If you're not using the build script to manage your filename version revving, | |
# you might want to consider enabling this, which will route requests for | |
# /css/style.20110203.css to /css/style.css | |
# To understand why this is important and a better idea than all.css?v1231, | |
# read: github.com/h5bp/html5-boilerplate/wiki/cachebusting | |
# <IfModule mod_rewrite.c> | |
# RewriteCond %{REQUEST_FILENAME} !-f | |
# RewriteCond %{REQUEST_FILENAME} !-d | |
# RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L] | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# Prevent SSL cert warnings | |
# ---------------------------------------------------------------------- | |
# Rewrite secure requests properly to prevent SSL cert warnings, e.g. prevent | |
# https://www.example.com when your cert only allows https://secure.example.com | |
# <IfModule mod_rewrite.c> | |
# RewriteCond %{SERVER_PORT} !^443 | |
# RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] | |
# </IfModule> | |
# ---------------------------------------------------------------------- | |
# Prevent 404 errors for non-existing redirected folders | |
# ---------------------------------------------------------------------- | |
# without -MultiViews, Apache will give a 404 for a rewrite if a folder of the | |
# same name does not exist. | |
# webmasterworld.com/apache/3808792.htm | |
Options -MultiViews | |
# ---------------------------------------------------------------------- | |
# Custom 404 page | |
# ---------------------------------------------------------------------- | |
# You can add custom pages to handle 500 or 403 pretty easily, if you like. | |
# If you are hosting your site in subdirectory, adjust this accordingly | |
# e.g. ErrorDocument 404 /subdir/404.html | |
ErrorDocument 404 /404.html | |
# ---------------------------------------------------------------------- | |
# UTF-8 encoding | |
# ---------------------------------------------------------------------- | |
# Use UTF-8 encoding for anything served text/plain or text/html | |
AddDefaultCharset utf-8 | |
# Force UTF-8 for a number of file formats | |
AddCharset utf-8 .atom .css .js .json .rss .vtt .xml | |
# ---------------------------------------------------------------------- | |
# A little more security | |
# ---------------------------------------------------------------------- | |
# To avoid displaying the exact version number of Apache being used, add the | |
# following to httpd.conf (it will not work in .htaccess): | |
# ServerTokens Prod | |
# "-Indexes" will have Apache block users from browsing folders without a | |
# default document Usually you should leave this activated, because you | |
# shouldn't allow everybody to surf through every folder on your server (which | |
# includes rather private places like CMS system folders). | |
<IfModule mod_autoindex.c> | |
Options -Indexes | |
</IfModule> | |
# Block access to "hidden" directories or files whose names begin with a | |
# period. This includes directories used by version control systems such as | |
# Subversion or Git. | |
<IfModule mod_rewrite.c> | |
RewriteCond %{SCRIPT_FILENAME} -d [OR] | |
RewriteCond %{SCRIPT_FILENAME} -f | |
RewriteRule "(^|/)\." - [F] | |
</IfModule> | |
# Block access to backup and source files. These files may be left by some | |
# text/html editors and pose a great security danger, when anyone can access | |
# them. | |
<FilesMatch "(\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$"> | |
Order allow,deny | |
Deny from all | |
Satisfy All | |
</FilesMatch> | |
# If your server is not already configured as such, the following directive | |
# should be uncommented in order to set PHP's register_globals option to OFF. | |
# This closes a major security hole that is abused by most XSS (cross-site | |
# scripting) attacks. For more information: http://php.net/register_globals | |
# | |
# IF REGISTER_GLOBALS DIRECTIVE CAUSES 500 INTERNAL SERVER ERRORS: | |
# | |
# Your server does not allow PHP directives to be set via .htaccess. In that | |
# case you must make this change in your php.ini file instead. If you are | |
# using a commercial web host, contact the administrators for assistance in | |
# doing this. Not all servers allow local php.ini files, and they should | |
# include all PHP configurations (not just this one), or you will effectively | |
# reset everything to PHP defaults. Consult www.php.net for more detailed | |
# information about setting PHP directives. | |
# php_flag register_globals Off | |
# Rename session cookie to something else, than PHPSESSID | |
# php_value session.name sid | |
# Disable magic quotes (This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.) | |
# php_flag magic_quotes_gpc Off | |
# Do not show you are using PHP | |
# Note: Move this line to php.ini since it won't work in .htaccess | |
# php_flag expose_php Off | |
# Level of log detail - log all errors | |
# php_value error_reporting -1 | |
# Write errors to log file | |
# php_flag log_errors On | |
# Do not display errors in browser (production - Off, development - On) | |
# php_flag display_errors Off | |
# Do not display startup errors (production - Off, development - On) | |
# php_flag display_startup_errors Off | |
# Format errors in plain text | |
# Note: Leave this setting 'On' for xdebug's var_dump() output | |
# php_flag html_errors Off | |
# Show multiple occurrence of error | |
# php_flag ignore_repeated_errors Off | |
# Show same errors from different sources | |
# php_flag ignore_repeated_source Off | |
# Size limit for error messages | |
# php_value log_errors_max_len 1024 | |
# Don't precede error with string (doesn't accept empty string, use whitespace if you need) | |
# php_value error_prepend_string " " | |
# Don't prepend to error (doesn't accept empty string, use whitespace if you need) | |
# php_value error_append_string " " | |
# Increase cookie security | |
<IfModule php5_module> | |
php_value session.cookie_httponly true | |
</IfModule> | |
scannr |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="CompilerConfiguration"> | |
<option name="DEFAULT_COMPILER" value="Javac" /> | |
<resourceExtensions /> | |
<wildcardResourcePatterns> | |
<entry name="!?*.java" /> | |
<entry name="!?*.form" /> | |
<entry name="!?*.class" /> | |
<entry name="!?*.groovy" /> | |
<entry name="!?*.scala" /> | |
<entry name="!?*.flex" /> | |
<entry name="!?*.kt" /> | |
<entry name="!?*.clj" /> | |
</wildcardResourcePatterns> | |
<annotationProcessing> | |
<profile default="true" name="Default" enabled="false"> | |
<processorPath useClasspath="true" /> | |
</profile> | |
</annotationProcessing> | |
</component> | |
</project> | |
<component name="CopyrightManager"> | |
<settings default=""> | |
<module2copyright /> | |
</settings> | |
</component> |
<component name="ProjectDictionaryState"> | |
<dictionary name="Madoka"> | |
<words> | |
<w>tgid</w> | |
<w>timefrom</w> | |
<w>timeto</w> | |
<w>tzoffset</w> | |
</words> | |
</dictionary> | |
</component> |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> | |
</project> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectResources"> | |
<default-html-doctype>jar:file:\C:\Program Files (x86)\JetBrains\PhpStorm 5.0.2\lib\webide.jar!\resources\html5-schema\html5.rnc</default-html-doctype> | |
</component> | |
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_3" assert-keyword="false" jdk-15="false" /> | |
</project> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectModuleManager"> | |
<modules> | |
<module fileurl="file://$PROJECT_DIR$/.idea/scannr.iml" filepath="$PROJECT_DIR$/.idea/scannr.iml" /> | |
</modules> | |
</component> | |
</project> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<module type="WEB_MODULE" version="4"> | |
<component name="FacetManager"> | |
<facet type="Python" name="Python"> | |
<configuration sdkName="" /> | |
</facet> | |
</component> | |
<component name="NewModuleRootManager" inherit-compiler-output="false"> | |
<content url="file://$MODULE_DIR$" /> | |
<orderEntry type="inheritedJdk" /> | |
<orderEntry type="sourceFolder" forTests="false" /> | |
</component> | |
</module> | |
<component name="DependencyValidationManager"> | |
<state> | |
<option name="SKIP_IMPORT_STATEMENTS" value="false" /> | |
</state> | |
</component> |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="SqlDialectMappings"> | |
<file url="file://$PROJECT_DIR$/db.sql" dialect="PostgreSQL" /> | |
</component> | |
</project> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="Palette2"> | |
<group name="Swing"> | |
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> | |
</item> | |
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> | |
</item> | |
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> | |
</item> | |
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true"> | |
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> | |
</item> | |
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> | |
<initial-values> | |
<property name="text" value="Button" /> | |
</initial-values> | |
</item> | |
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> | |
<initial-values> | |
<property name="text" value="RadioButton" /> | |
</initial-values> | |
</item> | |
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> | |
<initial-values> | |
<property name="text" value="CheckBox" /> | |
</initial-values> | |
</item> | |
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> | |
<initial-values> | |
<property name="text" value="Label" /> | |
</initial-values> | |
</item> | |
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> | |
<preferred-size width="150" height="-1" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> | |
<preferred-size width="150" height="-1" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> | |
<preferred-size width="150" height="-1" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |
<preferred-size width="150" height="50" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |
<preferred-size width="150" height="50" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |
<preferred-size width="150" height="50" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> | |
</item> | |
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |
<preferred-size width="150" height="50" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> | |
<preferred-size width="150" height="50" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> | |
<preferred-size width="150" height="50" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> | |
<preferred-size width="200" height="200" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> | |
<preferred-size width="200" height="200" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> | |
</item> | |
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> | |
</item> | |
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> | |
</item> | |
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> | |
</item> | |
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> | |
<preferred-size width="-1" height="20" /> | |
</default-constraints> | |
</item> | |
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false"> | |
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> | |
</item> | |
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> | |
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> | |
</item> | |
</group> | |
</component> | |
</project> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="VcsDirectoryMappings"> | |
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |
<mapping directory="$PROJECT_DIR$/pynma" vcs="Git" /> | |
</component> | |
</project> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Page Not Found :(</title> | |
<style> | |
::-moz-selection { | |
background: #b3d4fc; | |
text-shadow: none; | |
} | |
::selection { | |
background: #b3d4fc; | |
text-shadow: none; | |
} | |
html { | |
padding: 30px 10px; | |
font-size: 20px; | |
line-height: 1.4; | |
color: #737373; | |
background: #f0f0f0; | |
-webkit-text-size-adjust: 100%; | |
-ms-text-size-adjust: 100%; | |
} | |
html, | |
input { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
} | |
body { | |
max-width: 500px; | |
_width: 500px; | |
padding: 30px 20px 50px; | |
border: 1px solid #b3b3b3; | |
border-radius: 4px; | |
margin: 0 auto; | |
box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff; | |
background: #fcfcfc; | |
} | |
h1 { | |
margin: 0 10px; | |
font-size: 50px; | |
text-align: center; | |
} | |
h1 span { | |
color: #bbb; | |
} | |
h3 { | |
margin: 1.5em 0 0.5em; | |
} | |
p { | |
margin: 1em 0; | |
} | |
ul { | |
padding: 0 0 0 40px; | |
margin: 1em 0; | |
} | |
.container { | |
max-width: 380px; | |
_width: 380px; | |
margin: 0 auto; | |
} | |
/* google search */ | |
#goog-fixurl ul { | |
list-style: none; | |
padding: 0; | |
margin: 0; | |
} | |
#goog-fixurl form { | |
margin: 0; | |
} | |
#goog-wm-qt, | |
#goog-wm-sb { | |
border: 1px solid #bbb; | |
font-size: 16px; | |
line-height: normal; | |
vertical-align: top; | |
color: #444; | |
border-radius: 2px; | |
} | |
#goog-wm-qt { | |
width: 220px; | |
height: 20px; | |
padding: 5px; | |
margin: 5px 10px 0 0; | |
box-shadow: inset 0 1px 1px #ccc; | |
} | |
#goog-wm-sb { | |
display: inline-block; | |
height: 32px; | |
padding: 0 10px; | |
margin: 5px 0 0; | |
white-space: nowrap; | |
cursor: pointer; | |
background-color: #f5f5f5; | |
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0), #f1f1f1); | |
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0), #f1f1f1); | |
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0), #f1f1f1); | |
background-image: -o-linear-gradient(rgba(255, 255, 255, 0), #f1f1f1); | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
*overflow: visible; | |
*display: inline; | |
*zoom: 1; | |
} | |
#goog-wm-sb:hover, | |
#goog-wm-sb:focus { | |
border-color: #aaa; | |
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); | |
background-color: #f8f8f8; | |
} | |
#goog-wm-qt:hover, | |
#goog-wm-qt:focus { | |
border-color: #105cb6; | |
outline: 0; | |
color: #222; | |
} | |
input::-moz-focus-inner { | |
padding: 0; | |
border: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Not found <span>:(</span></h1> | |
<p>Sorry, but the page you were trying to view does not exist.</p> | |
<p>It looks like this was the result of either:</p> | |
<ul> | |
<li>a mistyped address</li> | |
<li>an out-of-date link</li> | |
</ul> | |
<script> | |
var GOOG_FIXURL_LANG = (navigator.language || '').slice(0, 2), GOOG_FIXURL_SITE = location.host; | |
</script> | |
<script src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script> | |
</div> | |
</body> | |
</html> | |
### HEAD | |
### 4.0.0 (28 August, 2012) | |
* Improve the Apache compression configuration ([#1012](https://github.com/h5bp/html5-boilerplate/issues/1012), [#1173](https://github.com/h5bp/html5-boilerplate/issues/1173)). | |
* Add a HiDPI example media query ([#1127](https://github.com/h5bp/html5-boilerplate/issues/1127)). | |
* Add bundled docs ([#1154](https://github.com/h5bp/html5-boilerplate/issues/1154)). | |
* Add MIT license ([#1139](https://github.com/h5bp/html5-boilerplate/issues/1139)). | |
* Update to Normalize.css 1.0.1. | |
* Separate Normalize.css from the rest of the CSS ([#1160](https://github.com/h5bp/html5-boilerplate/issues/1160)). | |
* Improve `console.log` protection ([#1107](https://github.com/h5bp/html5-boilerplate/issues/1107)). | |
* Replace hot pink text selection color with a neutral color. | |
* Change image replacement technique ([#1149](https://github.com/h5bp/html5-boilerplate/issues/1149)). | |
* Code format and consistency changes ([#1112](https://github.com/h5bp/html5-boilerplate/issues/1112)). | |
* Rename CSS file and rename JS files and subdirectories. | |
* Update to jQuery 1.8 ([#1161](https://github.com/h5bp/html5-boilerplate/issues/1161)). | |
* Update to Modernizr 2.6.1 ([#1086](https://github.com/h5bp/html5-boilerplate/issues/1086)). | |
* Remove uncompressed jQuery ([#1153](https://github.com/h5bp/html5-boilerplate/issues/1153)). | |
* Remove superfluous inline comments ([#1150](https://github.com/h5bp/html5-boilerplate/issues/1150)). | |
### 3.0.2 (February 19, 2012) | |
* Update to Modernizr 2.5.3. | |
### 3.0.1 (February 08, 2012). | |
* Update to Modernizr 2.5.2 (includes html5shiv 3.3). | |
### 3.0.0 (February 06, 2012) | |
* Improvements to `.htaccess`. | |
* Improve 404 design. | |
* Simplify JS folder structure. | |
* Change `html` IE class names changed to target ranges rather than specific versions of IE. | |
* Update CSS to include latest normalize.css changes and better typographic defaults ([#825](https://github.com/h5bp/html5-boilerplate/issues/825)). | |
* Update to Modernizr 2.5 (includes yepnope 1.5 and html5shiv 3.2). | |
* Update to jQuery 1.7.1. | |
* Revert to async snippet for the Google Analytics script. | |
* Remove the ant build script ([#826](https://github.com/h5bp/html5-boilerplate/issues/826)). | |
* Remove Respond.js ([#816](https://github.com/h5bp/html5-boilerplate/issues/816)). | |
* Remove the `demo/` directory ([#808](https://github.com/h5bp/html5-boilerplate/issues/808)). | |
* Remove the `test/` directory ([#808](https://github.com/h5bp/html5-boilerplate/issues/808)). | |
* Remove Google Chrome Frame script for IE6 users; replace with links to Chrome Frame and options for alternative browsers. | |
* Remove `initial-scale=1` from the viewport `meta` ([#824](https://github.com/h5bp/html5-boilerplate/issues/824)). | |
* Remove `defer` from all scripts to avoid legacy IE bugs. | |
* Remove explicit Site Speed tracking for Google Analytics. It's now enabled by default. | |
### 2.0.0 (August 10, 2011) | |
* Change starting CSS to be based on normalize.css instead of reset.css ([#500](https://github.com/h5bp/html5-boilerplate/issues/500)). | |
* Add Respond.js media query polyfill. | |
* Add Google Chrome Frame script prompt for IE6 users. | |
* Simplify the `html` conditional comments for modern browsers and add an `oldie` class. | |
* Update clearfix to use "micro clearfix". | |
* Add placeholder CSS MQs for mobile-first approach. | |
* Add `textarea { resize: vertical; }` to only allow vertical resizing. | |
* Add `img { max-width: 100%; }` to the print styles; prevents images being truncated. | |
* Add Site Speed tracking for Google Analytics. | |
* Update to jQuery 1.6.2 (and use minified by default). | |
* Update to Modernizr 2.0 Complete, Production minified (includes yepnope, html5shiv, and Respond.js). | |
* Use `Modernizr.load()` to load the Google Analytics script. | |
* Much faster build process. | |
* Add build script options for CSSLint, JSLint, JSHint tools. | |
* Build script now compresses all images in subfolders. | |
* Build script now versions files by SHA hash. | |
* Many `.htaccess` improvements including: disable directory browsing, improved support for all versions of Apache, more robust and extensive HTTP compression rules. | |
* Remove `handheld.css` as it has very poor device support. | |
* Remove touch-icon `link` elements from the HTML and include improved touch-icon support. | |
* Remove the cache-busting query paramaters from files references in the HTML. | |
* Remove IE6 PNGFix. | |
### 1.0.0 (March 21, 2011) | |
* Rewrite build script to make it more customizable and flexible. | |
* Add a humans.txt. | |
* Numerous `.htaccess` improvements (including inline documentation). | |
* Move the alternative server configurations to the H5BP server configs repo. | |
* Use a protocol-relative url to reference jQuery and prevent mixed content warnings. | |
* Optimize the Google Analytics snippet. | |
* Use Eric Meyer's recent CSS reset update and the HTML5 Doctor reset. | |
* More robust `sub`/`sup` CSS styles. | |
* Add keyboard `.focusable` helper class that extends `.visuallyhidden`. | |
* Print styles no longer print hash or JavaScript links. | |
* Add a print reset for IE's proprietary filters. | |
* Remove IE9-specific conditional class on the `html` element. | |
* Remove margins from lists within `nav` elements. | |
* Remove YUI profiling. | |
Copyright (c) HTML5 Boilerplate | |
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. | |
ffmpeg from http://ffmpeg.zeranoe.com/builds/ |
Binary files /dev/null and b/apple-touch-icon-114x114-precomposed.png differ
Binary files /dev/null and b/apple-touch-icon-144x144-precomposed.png differ
Binary files /dev/null and b/apple-touch-icon-57x57-precomposed.png differ
Binary files /dev/null and b/apple-touch-icon-72x72-precomposed.png differ
Binary files /dev/null and b/apple-touch-icon-precomposed.png differ
Binary files /dev/null and b/apple-touch-icon.png differ
<?php | |
include ('common.inc.php'); | |
$sth = $conn->prepare('select * from recordings | |
order by call_timestamp desc limit 1000'); | |
$sth->execute(Array()); | |
$row = 0; | |
echo "<table>"; | |
foreach ($sth->fetchAll() as $data) { | |
echo "<tr>"; | |
for ($c = 0; $c < count($data); $c++) { | |
echo '<td>' . $data[$c] . "</td>\n"; | |
} | |
echo "</tr>"; | |
} | |
$row++; | |
echo "</table>"; | |
<?php | |
include('common.inc.php'); | |
function getTGIDValuesByHour($TGID, $timeFrom, $timeTo) | |
{ | |
global $conn; | |
$sth = $conn->prepare('select tgid, min(call_timestamp) as time, count(*), min(length), max(length), avg(length), stddev(length) from recordings | |
where call_timestamp between to_timestamp(?) and to_timestamp(?) | |
group by tgid, date_trunc(\'hour\', call_timestamp) order by time'); | |
$sth->execute(Array($timeFrom, $timeTo)); | |
return $sth->fetchAll(PDO::FETCH_ASSOC); | |
} | |
function getTGIDValuesByDay($TGID, $dayFrom, $dayTo) | |
{ | |
global $conn; | |
$sth = $conn->prepare('select min(time) as time, min(value), max(value), avg(value), stddev(value) from sensor_values where sensor_id = ? | |
group by sensor_id, date_trunc(\'day\', time) order by time'); | |
$sth->execute(Array($TGID)); | |
return $sth->fetchAll(PDO::FETCH_ASSOC); | |
} | |
function getTGIDDataYears($TGID, $timeFrom, $timeTo) | |
{ | |
global $conn; | |
$sth = $conn->prepare("select distinct extract('year' from call_timestamp) as year from recordings where tgid = ? order by year"); | |
$sth->execute(Array($TGID)); | |
return $sth->fetchAll(PDO::FETCH_ASSOC); | |
} | |
function getTGIDDataMonths($TGID, $timeFrom, $timeTo) | |
{ | |
global $conn; | |
$sth = $conn->prepare("select distinct extract('month' from call_timestamp) as month, extract('year' from call_timestamp) as year from recordings where tgid = ? order by year, month"); | |
$sth->execute(Array($TGID)); | |
return $sth->fetchAll(PDO::FETCH_ASSOC); | |
} | |
function getTGIDDataDays($TGID, $timeFrom, $timeTo) | |
{ | |
global $conn; | |
$sth = $conn->prepare("select distinct extract('day' from call_timestamp) as day, extract('month' from call_timestamp) as month, extract('year' from call_timestamp) as year from recordings where tgid = ? order by year,month,day"); | |
$sth->execute(Array($TGID)); | |
return $sth->fetchAll(PDO::FETCH_ASSOC); | |
} | |
$action = (isset($_REQUEST['action']) ? $_REQUEST['action'] : ''); | |
$TGID = (isset($_REQUEST['tgid']) ? $_REQUEST['tgid'] : ''); | |
$timefrom = (isset($_REQUEST['from']) ? $_REQUEST['from'] : ''); | |
$timeto = (isset($_REQUEST['to']) ? $_REQUEST['to'] : ''); | |
if ($action == "data") { | |
$sth = $conn->prepare('select * from recordings | |
order by call_timestamp desc limit 100'); | |
$sth->execute(Array()); | |
echo json_encode ($sth->fetchAll(PDO::FETCH_ASSOC)); | |
} | |
if ($action == "data_description") { | |
$timefrom = strtotime($timefrom); | |
$timeto = strtotime($timeto); | |
$years = getTGIDDataYears($TGID, $timefrom, $timeto); | |
$months = getTGIDDataMonths($TGID, $timefrom, $timeto); | |
$days = getTGIDDataDays($TGID, $timefrom, $timeto); | |
echo json_encode(Array("years" => $years, "months" => $months, "days" => $days | |
)); | |
} | |
if (strpos($action, "graph") !== false) { | |
$values = getTGIDValuesByHour($TGID, $timefrom, $timeto); | |
$label = $TGID; | |
$data = Array(); | |
$tzoffset = get_timezone_offset("UTC"); | |
foreach ($values as $value) { | |
if ($action == "graphlength") { | |
$data[$value['tgid']][] = Array((strtotime($value['time']) + $tzoffset) * 1000, intval($value['avg'])); | |
} else if ($action == "graphcount") { | |
$data[$value['tgid']][] = Array((strtotime($value['time']) + $tzoffset) * 1000, intval($value['count'])); | |
} | |
} | |
echo json_encode(Array("label" => $label, "data" => $data, | |
"previous" => Array( | |
"from" => $timefrom - (24 * 60 * 60), | |
"to" => $timefrom) | |
, | |
"next" => Array( | |
"to" => $timeto + (24 * 60 * 60), | |
"from" => $timeto) | |
) | |
); | |
} | |
?> | |
<?php | |
date_default_timezone_set("Australia/Sydney"); | |
try { | |
$conn = new PDO("pgsql:dbname=scannr;user=postgres;password=snmc;host=localhost"); | |
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
} catch (PDOException $e) { | |
die('Unable to connect to database server.'); | |
} | |
catch (Exception $e) { | |
die('Unknown error in ' . __FILE__ . '.'); | |
} | |
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); | |
$basePath = ""; | |
$DATA_DIR = "./data"; | |
/** Returns the offset from the origin timezone to the remote timezone, in seconds. | |
* @param $remote_tz; | |
* @param $origin_tz; If null the servers current timezone is used as the origin. | |
* @return int; | |
*/ | |
function get_timezone_offset($remote_tz, $origin_tz = null) | |
{ | |
if ($origin_tz === null) { | |
if (!is_string($origin_tz = date_default_timezone_get())) { | |
return false; // A UTC timestamp was returned -- bail out! | |
} | |
} | |
$origin_dtz = new DateTimeZone($origin_tz); | |
$remote_dtz = new DateTimeZone($remote_tz); | |
$origin_dt = new DateTime("now", $origin_dtz); | |
$remote_dt = new DateTime("now", $remote_dtz); | |
$offset = $origin_dtz->getOffset($origin_dt) - $remote_dtz->getOffset($remote_dt); | |
return $offset; | |
} | |
function include_header($title) | |
{ | |
global $basePath; | |
?> | |
<!DOCTYPE html> | |
<!--[if lt IE 7]> | |
<html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | |
<!--[if IE 7]> | |
<html class="no-js lt-ie9 lt-ie8"> <![endif]--> | |
<!--[if IE 8]> | |
<html class="no-js lt-ie9"> <![endif]--> | |
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | |
<title></title> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width"> | |
<!-- Place favicon.ico and apple-touch-icon.png in the root directory --> | |
<link rel="stylesheet" href="css/normalize.css"> | |
<link rel="stylesheet" href="css/main.css"> | |
<link href="css/daterangepicker.css" rel="stylesheet"> | |
<script src="js/vendor/modernizr-2.6.1.min.js"></script> | |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script> | |
<!--<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.8.0.min.js"><\/script>')</script>--> | |
<script type="text/javascript" src="<?php echo $basePath ?>js/flotr2/flotr2.js"></script> | |
<script src="js/plugins.js"></script> | |
<script src="js/main.js"></script> | |
<!-- xcharts includes --> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.js"></script> | |
<!-- The daterange picker bootstrap plugin --> | |
<script src="js/sugar.min.js"></script> | |
<script src="js/daterangepicker.js"></script> | |
</head> | |
<body> | |
<!--[if lt IE 7]> | |
<p class="chromeframe">You are using an outdated browser. <a href="http://browsehappy.com/">Upgrade your browser | |
today</a> or <a href="http://www.google.com/chromeframe/?redirect=true">install Google Chrome Frame</a> to | |
better experience this site.</p> | |
<![endif]--> | |
<!-- Add your site or application content here --> | |
<?php | |
} | |
function include_footer() | |
{ | |
global $basePath; | |
?> | |
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. --> | |
<script> | |
var _gaq = [ | |
['_setAccount', 'UA-XXXXX-X'], | |
['_trackPageview'] | |
]; | |
(function (d, t) { | |
var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; | |
g.src = ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js'; | |
s.parentNode.insertBefore(g, s) | |
}(document, 'script')); | |
</script> | |
</body> | |
</html> | |
<?php | |
} | |
<?xml version="1.0"?> | |
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> | |
<cross-domain-policy> | |
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html --> | |
<!-- Most restrictive policy: --> | |
<site-control permitted-cross-domain-policies="none"/> | |
<!-- Least restrictive policy: --> | |
<!-- | |
<site-control permitted-cross-domain-policies="all"/> | |
<allow-access-from domain="*" to-ports="*" secure="false"/> | |
<allow-http-request-headers-from domain="*" headers="*" secure="false"/> | |
--> | |
</cross-domain-policy> | |
.daterangepicker.dropdown-menu { | |
max-width: none; | |
} | |
.daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar { | |
float: left; | |
margin: 4px; | |
} | |
.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar { | |
float: right; | |
margin: 4px; | |
} | |
.daterangepicker .ranges { | |
width: 160px; | |
text-align: left; | |
} | |
.daterangepicker .ranges .range_inputs>div { | |
float: left; | |
} | |
.daterangepicker .ranges .range_inputs>div:nth-child(2) { | |
padding-left: 11px; | |
} | |
.daterangepicker .calendar { | |
display: none; | |
max-width: 230px; | |
} | |
.daterangepicker .calendar th, .daterangepicker .calendar td { | |
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
white-space: nowrap; | |
text-align: center; | |
} | |
.daterangepicker .ranges label { | |
color: #333; | |
font-size: 11px; | |
margin-bottom: 2px; | |
text-transform: uppercase; | |
text-shadow: 1px 1px 0 #fff; | |
} | |
.daterangepicker .ranges input { | |
font-size: 11px; | |
} | |
.daterangepicker .ranges ul { | |
list-style: none; | |
margin: 0; | |
padding: 0; | |
} | |
.daterangepicker .ranges li { | |
font-size: 13px; | |
background: #f5f5f5; | |
border: 1px solid #f5f5f5; | |
color: #08c; | |
padding: 3px 12px; | |
margin-bottom: 8px; | |
-webkit-border-radius: 5px; | |
-moz-border-radius: 5px; | |
border-radius: 5px; | |
cursor: pointer; | |
} | |
.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover { | |
background: #08c; | |
border: 1px solid #08c; | |
color: #fff; | |
} | |
.daterangepicker .calendar { | |
border: 1px solid #ddd; | |
padding: 4px; | |
border-radius: 4px; | |
background: #fff; | |
} | |
.daterangepicker { | |
position: absolute; | |
background: #fff; | |
top: 100px; | |
left: 20px; | |
padding: 4px; | |
margin-top: 1px; | |
-webkit-border-radius: 4px; | |
-moz-border-radius: 4px; | |
border-radius: 4px; | |
} | |
.daterangepicker.opensleft:before { | |
position: absolute; | |
top: -7px; | |
right: 9px; | |
display: inline-block; | |
border-right: 7px solid transparent; | |
border-bottom: 7px solid #ccc; | |
border-left: 7px solid transparent; | |
border-bottom-color: rgba(0, 0, 0, 0.2); | |
content: ''; | |
} | |
.daterangepicker.opensleft:after { | |
position: absolute; | |
top: -6px; | |
right: 10px; | |
display: inline-block; | |
border-right: 6px solid transparent; | |
border-bottom: 6px solid #fff; | |
border-left: 6px solid transparent; | |
content: ''; | |
} | |
.daterangepicker.opensright:before { | |
position: absolute; | |
top: -7px; | |
left: 9px; | |
display: inline-block; | |
border-right: 7px solid transparent; | |
border-bottom: 7px solid #ccc; | |
border-left: 7px solid transparent; | |
border-bottom-color: rgba(0, 0, 0, 0.2); | |
content: ''; | |
} | |
.daterangepicker.opensright:after { | |
position: absolute; | |
top: -6px; | |
left: 10px; | |
display: inline-block; | |
border-right: 6px solid transparent; | |
border-bottom: 6px solid #fff; | |
border-left: 6px solid transparent; | |
content: ''; | |
} | |
.daterangepicker table { | |
width: 100%; | |
margin: 0; | |
} | |
.daterangepicker td, .daterangepicker th { | |
text-align: center; | |
width: 20px; | |
height: 20px; | |
-webkit-border-radius: 4px; | |
-moz-border-radius: 4px; | |
border-radius: 4px; | |
cursor: pointer; | |
white-space: nowrap; | |
} | |
.daterangepicker td.off { | |
color: #999; | |
} | |
.daterangepicker td.disabled { | |
color: #999; | |
} | |
.daterangepicker td.available:hover, .daterangepicker th.available:hover { | |
background: #eee; | |
} | |
.daterangepicker td.in-range { | |
background: #ebf4f8; | |
-webkit-border-radius: 0; | |
-moz-border-radius: 0; | |
border-radius: 0; | |
} | |
.daterangepicker td.active, .daterangepicker td.active:hover { | |
background-color: #006dcc; | |
background-image: -moz-linear-gradient(top, #0088cc, #0044cc); | |
background-image: -ms-linear-gradient(top, #0088cc, #0044cc); | |
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); | |
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); | |
background-image: -o-linear-gradient(top, #0088cc, #0044cc); | |
background-image: linear-gradient(top, #0088cc, #0044cc); | |
background-repeat: repeat-x; | |
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); | |
border-color: #0044cc #0044cc #002a80; | |
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); | |
color: #fff; | |
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
} | |
.daterangepicker td.week, .daterangepicker th.week { | |
font-size: 80%; | |
color: #ccc; | |
} | |
/* | |
* HTML5 Boilerplate | |
* | |
* What follows is the result of much research on cross-browser styling. | |
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, | |
* Kroc Camen, and the H5BP dev community and team. | |
*/ | |
/* ========================================================================== | |
Base styles: opinionated defaults | |
========================================================================== */ | |
html, | |
button, | |
input, | |
select, | |
textarea { | |
color: #222; | |
} | |
body { | |
font-size: 1em; | |
line-height: 1.4; | |
} | |
/* | |
* Remove text-shadow in selection highlight: h5bp.com/i | |
* These selection declarations have to be separate. | |
* Customize the background color to match your design. | |
*/ | |
::-moz-selection { | |
background: #b3d4fc; | |
text-shadow: none; | |
} | |
::selection { | |
background: #b3d4fc; | |
text-shadow: none; | |
} | |
/* | |
* A better looking default horizontal rule | |
*/ | |
hr { | |
display: block; | |
height: 1px; | |
border: 0; | |
border-top: 1px solid #ccc; | |
margin: 1em 0; | |
padding: 0; | |
} | |
/* | |
* Remove the gap between images and the bottom of their containers: h5bp.com/i/440 | |
*/ | |
img { | |
vertical-align: middle; | |
} | |
/* | |
* Remove default fieldset styles. | |
*/ | |
fieldset { | |
border: 0; | |
margin: 0; | |
padding: 0; | |
} | |
/* | |
* Allow only vertical resizing of textareas. | |
*/ | |
textarea { | |
resize: vertical; | |
} | |
/* ========================================================================== | |
Chrome Frame prompt | |
========================================================================== */ | |
.chromeframe { | |
margin: 0.2em 0; | |
background: #ccc; | |
color: #000; | |
padding: 0.2em 0; | |
} | |
/* ========================================================================== | |
Author's custom styles | |
========================================================================== */ | |
/* ========================================================================== | |
Helper classes | |
========================================================================== */ | |
/* | |
* Image replacement | |
*/ | |
.ir { | |
background-color: transparent; | |
border: 0; | |
overflow: hidden; | |
/* IE 6/7 fallback */ | |
*text-indent: -9999px; | |
} | |
.ir:before { | |
content: ""; | |
display: block; | |
width: 0; | |
height: 100%; | |
} | |
/* | |
* Hide from both screenreaders and browsers: h5bp.com/u | |
*/ | |
.hidden { | |
display: none !important; | |
visibility: hidden; | |
} | |
/* | |
* Hide only visually, but have it available for screenreaders: h5bp.com/v | |
*/ | |
.visuallyhidden { | |
border: 0; | |
clip: rect(0 0 0 0); | |
height: 1px; | |
margin: -1px; | |
overflow: hidden; | |
padding: 0; | |
position: absolute; | |
width: 1px; | |
} | |
/* | |
* Extends the .visuallyhidden class to allow the element to be focusable | |
* when navigated to via the keyboard: h5bp.com/p | |
*/ | |
.visuallyhidden.focusable:active, | |
.visuallyhidden.focusable:focus { | |
clip: auto; | |
height: auto; | |
margin: 0; | |
overflow: visible; | |
position: static; | |
width: auto; | |
} | |
/* | |
* Hide visually and from screenreaders, but maintain layout | |
*/ | |
.invisible { | |
visibility: hidden; | |
} | |
/* | |
* Clearfix: contain floats | |
* | |
* For modern browsers | |
* 1. The space content is one way to avoid an Opera bug when the | |
* `contenteditable` attribute is included anywhere else in the document. | |
* Otherwise it causes space to appear at the top and bottom of elements | |
* that receive the `clearfix` class. | |
* 2. The use of `table` rather than `block` is only necessary if using | |
* `:before` to contain the top-margins of child elements. | |
*/ | |
.clearfix:before, | |
.clearfix:after { | |
content: " "; /* 1 */ | |
display: table; /* 2 */ | |
} | |
.clearfix:after { | |
clear: both; | |
} | |
/* | |
* For IE 6/7 only | |
* Include this rule to trigger hasLayout and contain floats. | |
*/ | |
.clearfix { | |
*zoom: 1; | |
} | |
/* ========================================================================== | |
EXAMPLE Media Queries for Responsive Design. | |
Theses examples override the primary ('mobile first') styles. | |
Modify as content requires. | |
========================================================================== */ | |
@media only screen and (min-width: 35em) { | |
/* Style adjustments for viewports that meet the condition */ | |
} | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), | |
only screen and (min-resolution: 144dpi) { | |
/* Style adjustments for high resolution devices */ | |
} | |
/* ========================================================================== | |
Print styles. | |
Inlined to avoid required HTTP connection: h5bp.com/r | |
========================================================================== */ | |
@media print { | |
* { | |
background: transparent !important; | |
color: #000 !important; /* Black prints faster: h5bp.com/s */ | |
box-shadow:none !important; | |
text-shadow: none !important; | |
} | |
a, | |
a:visited { | |
text-decoration: underline; | |
} | |
a[href]:after { | |
content: " (" attr(href) ")"; | |
} | |
abbr[title]:after { | |
content: " (" attr(title) ")"; | |
} | |
/* | |
* Don't show links for images, or javascript/internal links | |
*/ | |
.ir a:after, | |
a[href^="javascript:"]:after, | |
a[href^="#"]:after { | |
content: ""; | |
} | |
pre, | |
blockquote { | |
border: 1px solid #999; | |
page-break-inside: avoid; | |
} | |
thead { | |
display: table-header-group; /* h5bp.com/t */ | |
} | |
tr, | |
img { | |
page-break-inside: avoid; | |
} | |
img { | |
max-width: 100% !important; | |
} | |
@page { | |
margin: 0.5cm; | |
} | |
p, | |
h2, | |
h3 { | |
orphans: 3; | |
widows: 3; | |
} | |
h2, | |
h3 { | |
page-break-after: avoid; | |
} | |
} | |
/*! normalize.css v1.0.1 | MIT License | git.io/normalize */ | |
/* ========================================================================== | |
HTML5 display definitions | |
========================================================================== */ | |
/* | |
* Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3. | |
*/ | |
article, | |
aside, | |
details, | |
figcaption, | |
figure, | |
footer, | |
header, | |
hgroup, | |
nav, | |
section, | |
summary { | |
display: block; | |
} | |
/* | |
* Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. | |
*/ | |
audio, | |
canvas, | |
video { | |
display: inline-block; | |
*display: inline; | |
*zoom: 1; | |
} | |
/* | |
* Prevents modern browsers from displaying `audio` without controls. | |
* Remove excess height in iOS 5 devices. | |
*/ | |
audio:not([controls]) { | |
display: none; | |
height: 0; | |
} | |
/* | |
* Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3, | |
* and Safari 4. | |
* Known issue: no IE 6 support. | |
*/ | |
[hidden] { | |
display: none; | |
} | |
/* ========================================================================== | |
Base | |
========================================================================== */ | |
/* | |
* 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using | |
* `em` units. | |
* 2. Prevents iOS text size adjust after orientation change, without disabling | |
* user zoom. | |
*/ | |
html { | |
font-size: 100%; /* 1 */ | |
-webkit-text-size-adjust: 100%; /* 2 */ | |
-ms-text-size-adjust: 100%; /* 2 */ | |
} | |
/* | |
* Addresses `font-family` inconsistency between `textarea` and other form | |
* elements. | |
*/ | |
html, | |
button, | |
input, | |
select, | |
textarea { | |
font-family: sans-serif; | |
} | |
/* | |
* Addresses margins handled incorrectly in IE 6/7. | |
*/ | |
body { | |
margin: 0; | |
} | |
/* ========================================================================== | |
Links | |
========================================================================== */ | |
/* | |
* Addresses `outline` inconsistency between Chrome and other browsers. | |
*/ | |
a:focus { | |
outline: thin dotted; | |
} | |
/* | |
* Improves readability when focused and also mouse hovered in all browsers. | |
*/ | |
a:active, | |
a:hover { | |
outline: 0; | |
} | |
/* ========================================================================== | |
Typography | |
========================================================================== */ | |
/* | |
* Addresses font sizes and margins set differently in IE 6/7. | |
* Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5, | |
* and Chrome. | |
*/ | |
h1 { | |
font-size: 2em; | |
margin: 0.67em 0; | |
} | |
h2 { | |
font-size: 1.5em; | |
margin: 0.83em 0; | |
} | |
h3 { | |
font-size: 1.17em; | |
margin: 1em 0; | |
} | |
h4 { | |
font-size: 1em; | |
margin: 1.33em 0; | |
} | |
h5 { | |
font-size: 0.83em; | |
margin: 1.67em 0; | |
} | |
h6 { | |
font-size: 0.75em; | |
margin: 2.33em 0; | |
} | |
/* | |
* Addresses styling not present in IE 7/8/9, Safari 5, and Chrome. | |
*/ | |
abbr[title] { | |
border-bottom: 1px dotted; | |
} | |
/* | |
* Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. | |
*/ | |
b, | |
strong { | |
font-weight: bold; | |
} | |
blockquote { | |
margin: 1em 40px; | |
} | |
/* | |
* Addresses styling not present in Safari 5 and Chrome. | |
*/ | |
dfn { | |
font-style: italic; | |
} | |
/* | |
* Addresses styling not present in IE 6/7/8/9. | |
*/ | |
mark { | |
background: #ff0; | |
color: #000; | |
} | |
/* | |
* Addresses margins set differently in IE 6/7. | |
*/ | |
p, | |
pre { | |
margin: 1em 0; | |
} | |
/* | |
* Corrects font family set oddly in IE 6, Safari 4/5, and Chrome. | |
*/ | |
code, | |
kbd, | |
pre, | |
samp { | |
font-family: monospace, serif; | |
_font-family: 'courier new', monospace; | |
font-size: 1em; | |
} | |
/* | |
* Improves readability of pre-formatted text in all browsers. | |
*/ | |
pre { | |
white-space: pre; | |
white-space: pre-wrap; | |
word-wrap: break-word; | |
} | |
/* | |
* Addresses CSS quotes not supported in IE 6/7. | |
*/ | |
q { | |
quotes: none; | |
} | |
/* | |
* Addresses `quotes` property not supported in Safari 4. | |
*/ | |
q:before, | |
q:after { | |
content: ''; | |
content: none; | |
} | |
/* | |
* Addresses inconsistent and variable font size in all browsers. | |
*/ | |
small { | |
font-size: 80%; | |
} | |
/* | |
* Prevents `sub` and `sup` affecting `line-height` in all browsers. | |
*/ | |
sub, | |
sup { | |
font-size: 75%; | |
line-height: 0; | |
position: relative; | |
vertical-align: baseline; | |
} | |
sup { | |
top: -0.5em; | |
} | |
sub { | |
bottom: -0.25em; | |
} | |
/* ========================================================================== | |
Lists | |
========================================================================== */ | |
/* | |
* Addresses margins set differently in IE 6/7. | |
*/ | |
dl, | |
menu, | |
ol, | |
ul { | |
margin: 1em 0; | |
} | |
dd { | |
margin: 0 0 0 40px; | |
} | |
/* | |
* Addresses paddings set differently in IE 6/7. | |
*/ | |
menu, | |
ol, | |
ul { | |
padding: 0 0 0 40px; | |
} | |
/* | |
* Corrects list images handled incorrectly in IE 7. | |
*/ | |
nav ul, | |
nav ol { | |
list-style: none; | |
list-style-image: none; | |
} | |
/* ========================================================================== | |
Embedded content | |
========================================================================== */ | |
/* | |
* 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3. | |
* 2. Improves image quality when scaled in IE 7. | |
*/ | |
img { | |
border: 0; /* 1 */ | |
-ms-interpolation-mode: bicubic; /* 2 */ | |
} | |
/* | |
* Corrects overflow displayed oddly in IE 9. | |
*/ | |
svg:not(:root) { | |
overflow: hidden; | |
} | |
/* ========================================================================== | |
Figures | |
========================================================================== */ | |
/* | |
* Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11. | |
*/ | |
figure { | |
margin: 0; | |
} | |
/* ========================================================================== | |
Forms | |
========================================================================== */ | |
/* | |
* Corrects margin displayed oddly in IE 6/7. | |
*/ | |
form { | |
margin: 0; | |
} | |
/* | |
* Define consistent border, margin, and padding. | |
*/ | |
fieldset { | |
border: 1px solid #c0c0c0; | |
margin: 0 2px; | |
padding: 0.35em 0.625em 0.75em; | |
} | |
/* | |
* 1. Corrects color not being inherited in IE 6/7/8/9. | |
* 2. Corrects text not wrapping in Firefox 3. | |
* 3. Corrects alignment displayed oddly in IE 6/7. | |
*/ | |
legend { | |
border: 0; /* 1 */ | |
padding: 0; | |
white-space: normal; /* 2 */ | |
*margin-left: -7px; /* 3 */ | |
} | |
/* | |
* 1. Corrects font size not being inherited in all browsers. | |
* 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5, | |
* and Chrome. | |
* 3. Improves appearance and consistency in all browsers. | |
*/ | |
button, | |
input, | |
select, | |
textarea { | |
font-size: 100%; /* 1 */ | |
margin: 0; /* 2 */ | |
vertical-align: baseline; /* 3 */ | |
*vertical-align: middle; /* 3 */ | |
} | |
/* | |
* Addresses Firefox 3+ setting `line-height` on `input` using `!important` in | |
* the UA stylesheet. | |
*/ | |
button, | |
input { | |
line-height: normal; | |
} | |
/* | |
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` | |
* and `video` controls. | |
* 2. Corrects inability to style clickable `input` types in iOS. | |
* 3. Improves usability and consistency of cursor style between image-type | |
* `input` and others. | |
* 4. Removes inner spacing in IE 7 without affecting normal text inputs. | |
* Known issue: inner spacing remains in IE 6. | |
*/ | |
button, | |
html input[type="button"], /* 1 */ | |
input[type="reset"], | |
input[type="submit"] { | |
-webkit-appearance: button; /* 2 */ | |
cursor: pointer; /* 3 */ | |
*overflow: visible; /* 4 */ | |
} | |
/* | |
* Re-set default cursor for disabled elements. | |
*/ | |
button[disabled], | |
input[disabled] { | |
cursor: default; | |
} | |
/* | |
* 1. Addresses box sizing set to content-box in IE 8/9. | |
* 2. Removes excess padding in IE 8/9. | |
* 3. Removes excess padding in IE 7. | |
* Known issue: excess padding remains in IE 6. | |
*/ | |
input[type="checkbox"], | |
input[type="radio"] { | |
box-sizing: border-box; /* 1 */ | |
padding: 0; /* 2 */ | |
*height: 13px; /* 3 */ | |
*width: 13px; /* 3 */ | |
} | |
/* | |
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. | |
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome | |
* (include `-moz` to future-proof). | |
*/ | |
input[type="search"] { | |
-webkit-appearance: textfield; /* 1 */ | |
-moz-box-sizing: content-box; | |
-webkit-box-sizing: content-box; /* 2 */ | |
box-sizing: content-box; | |
} | |
/* | |
* Removes inner padding and search cancel button in Safari 5 and Chrome | |
* on OS X. | |
*/ | |
input[type="search"]::-webkit-search-cancel-button, | |
input[type="search"]::-webkit-search-decoration { | |
-webkit-appearance: none; | |
} | |
/* | |
* Removes inner padding and border in Firefox 3+. | |
*/ | |
button::-moz-focus-inner, | |
input::-moz-focus-inner { | |
border: 0; | |
padding: 0; | |
} | |
/* | |
* 1. Removes default vertical scrollbar in IE 6/7/8/9. | |
* 2. Improves readability and alignment in all browsers. | |
*/ | |
textarea { | |
overflow: auto; /* 1 */ | |
vertical-align: top; /* 2 */ | |
} | |
/* ========================================================================== | |
Tables | |
========================================================================== */ | |
/* | |
* Remove most spacing between table cells. | |
*/ | |
table { | |
border-collapse: collapse; | |
border-spacing: 0; | |
} | |
bri<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Pretty Charts with jQuery and AJAX | Tutorialzine Demo</title> | |
<!-- Include bootstrap css --> | |
<link href="css/daterangepicker.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div id="content"> | |
<form class="form-horizontal"> | |
<fieldset> | |
<div class="input-prepend"> | |
<span class="add-on"><i class="icon-calendar"></i></span><input type="text" name="range" id="range" /> | |
</div> | |
</fieldset> | |
</form> | |
<div id="placeholder"> | |
<figure id="chart"></figure> | |
</div> | |
</div> | |
<footer> | |
<h2><i>Tutorial:</i> Pretty Charts with jQuery and AJAX</h2> | |
<a class="tzine" href="http://tutorialzine.com/2013/01/charts-jquery-ajax/">Head on to <i>Tutorial<b>zine</b></i> to read and download</a> | |
</footer> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> | |
<!-- xcharts includes --> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.js"></script> | |
<!-- The daterange picker bootstrap plugin --> | |
<script src="js/sugar.min.js"></script> | |
<script src="js/daterangepicker.js"></script> | |
<!-- Our main script file --> | |
<script src="js/script.js"></script> | |
</body> | |
</html> | |
-- /usr/pgsql-9.1/bin/pg_dump --schema-only scannr | |
-- | |
-- PostgreSQL database dump | |
-- | |
SET statement_timeout = 0; | |
SET client_encoding = 'UTF8'; | |
SET standard_conforming_strings = on; | |
SET check_function_bodies = false; | |
SET client_min_messages = warning; | |
-- | |
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: | |
-- | |
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; | |
-- | |
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: | |
-- | |
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; | |
SET search_path = public, pg_catalog; | |
SET default_tablespace = ''; | |
SET default_with_oids = false; | |
-- | |
-- Name: recordings; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE recordings ( | |
filename text NOT NULL, | |
tgid text, | |
tgname text, | |
sitename text, | |
call_timestamp timestamp with time zone DEFAULT now(), | |
length integer | |
); | |
ALTER TABLE public.recordings OWNER TO postgres; | |
-- | |
-- Name: tgids; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE tgids ( | |
tgid text NOT NULL, | |
subfleet smallint, | |
alpha_tag text NOT NULL, | |
mode character(1) DEFAULT 'D'::bpchar NOT NULL, | |
description text, | |
service_tag text, | |
category text | |
); | |
ALTER TABLE public.tgids OWNER TO postgres; | |
-- | |
-- Name: recordings_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY recordings | |
ADD CONSTRAINT recordings_pkey PRIMARY KEY (filename); | |
-- | |
-- Name: tgids_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY tgids | |
ADD CONSTRAINT tgids_pkey PRIMARY KEY (tgid); | |
-- | |
-- Name: public; Type: ACL; Schema: -; Owner: postgres | |
-- | |
REVOKE ALL ON SCHEMA public FROM PUBLIC; | |
REVOKE ALL ON SCHEMA public FROM postgres; | |
GRANT ALL ON SCHEMA public TO postgres; | |
GRANT ALL ON SCHEMA public TO PUBLIC; | |
-- | |
-- PostgreSQL database dump complete | |
-- | |
CREATE TABLE "compilations" ( | |
"filename" text NOT NULL, | |
"files" text ARRAY NOT NULL, | |
"datetime" timestamp NOT NULL | |
); | |
CREATE TABLE "trunk_logs" ( | |
"id" text NOT NULL, | |
"datetime" integer NOT NULL, | |
"site" integer NOT NULL, | |
"action" text NOT NULL, | |
"sourcetype" character(1) NOT NULL, | |
"sourceid" smallint NOT NULL, | |
"targettype" character(1) NOT NULL, | |
"targetid" smallint NOT NULL, | |
"channel" smallint NOT NULL, | |
"calltype" text NOT NULL | |
); | |
Binary files /dev/null and b/favicon.ico differ
\<?php | |
include('common.inc.php'); | |
function processHourly($hourly) { | |
global $conn; | |
$hfilename = str_replace(' ','_',$hourly['tgid']) . '-' . str_replace(Array(' 00:00:00+10',' 00:00:00+11'), '', $hourly['aday']) . '-' . $hourly['ahour'] . '.3gp'; | |
if (!file_exists("hourly/" . $hfilename)) { | |
$filenames = explode(",", $hourly['filenames']); | |
$cmd = "/usr/local/bin/ffmpeg"; | |
if (count($filenames) > 1) { | |
$cmd .=" -filter_complex concat=n=" . count($filenames) . ":v=0:a=1"; // only concat when more than 1 file | |
} | |
$cmd .=" -i data/" . implode(" -i data/", $filenames) . " -ar 8000 -ab 4.75k -ac 1 hourly/" . $hfilename . ' 2>&1'; | |
//print_r($hourly); | |
exec($cmd, $output, $returncode); | |
echo $cmd . "<br>\n"; | |
if ($returncode != 0) { | |
echo $returncode; | |
print_r($output); | |
unlink("hourly/" . $hfilename); // delete incomplete file | |
// die(); | |
} else { | |
$time = strtotime($hourly['aday'] . ' +' . $hourly['ahour'] . " hours"); | |
$q = " insert into compilations (filename,files,datetime) VALUES ('" . $hfilename . "', ARRAY['" . implode("', '", $filenames) . "'], to_timestamp('" . $time . "') );"; | |
$conn->query($q); | |
//echo $q."\n"; | |
foreach ($filenames as $filename) { | |
$q = "UPDATE recordings SET archived = '$hfilename' WHERE filename = '$filename' ;"; | |
$conn->query($q); | |
//echo $q."\n"; | |
} | |
//die(); | |
} | |
} | |
} | |
/*$sth = $conn->prepare("select tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, | |
count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames from recordings group by tgid, ahour, aday order by aday DESC, ahour, tgid;"); | |
// TODO use tgid categories instead, tgid too specific | |
$sth->execute(); | |
$hourlies = $sth->fetchAll(PDO::FETCH_ASSOC); | |
foreach ($hourlies as $hourly) { | |
processHourly($hourly); | |
} | |
$sth = $conn->prepare("select 'hour' as tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, | |
count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames from recordings group by ahour, aday order by aday DESC, ahour;"); | |
$sth->execute(); | |
$hourlies = $sth->fetchAll(PDO::FETCH_ASSOC); | |
foreach ($hourlies as $hourly) { | |
processHourly($hourly); | |
}*/ | |
$sth = $conn->prepare("select coalesce(category,'unknown') as tgid, extract(hour from call_timestamp) ahour, date_trunc('day', call_timestamp) aday, | |
count(filename), array_to_string(array_agg(filename order by call_timestamp), ',') filenames | |
from recordings inner join tgids on recordings.tgid = tgids.tgid | |
group by category, ahour, aday | |
having count(archived) != count(filename) | |
order by aday DESC, ahour, category;"); | |
$sth->execute(); | |
$hourlies = $sth->fetchAll(PDO::FETCH_ASSOC); | |
foreach($hourlies as $hourly) { | |
processHourly($hourly); | |
} | |
<?php | |
$reqfile = "path/to/file.3gp"; | |
$contenttype = "audio/3gpp"; | |
if ($fn = fopen($reqfile, "rba")) { | |
header("Content-Type: " . $contenttype); | |
header("Content-Length: " . filesize($reqfile)); | |
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | |
header("Pragma: no-cache"); | |
header("Expires: Mon, 26 Jul 1997 06:00:00 GMT"); | |
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0"); | |
passthru("ffmpeg -i 2012-09-29-1348911268.34-demo.wav -ar 8000 -ab 4.75k -"); | |
fpassthru($fn); | |
fclose($fn); | |
} else { | |
exit("error...."); | |
} | |
exit(); | |
?> | |
# humanstxt.org/ | |
# The humans responsible & technology colophon | |
# TEAM | |
<name> -- <role> -- <twitter> | |
# THANKS | |
<name> | |
# TECHNOLOGY COLOPHON | |
HTML5, CSS3 | |
jQuery, Modernizr | |
insert into tgids (tgid,alpha_tag) (SELECT distinct tgid, tgname as alpha_tag FROM recordings WHERE NOT EXISTS (SELECT tgid FROM tgids WHERE tgid=recordings.tgid)); | |
/** | |
* @version: 1.0.1 | |
* @author: Dan Grossman http://www.dangrossman.info/ | |
* @date: 2012-08-20 | |
* @copyright: Copyright (c) 2012 Dan Grossman. All rights reserved. | |
* @license: Licensed under Apache License v2.0. See http://www.apache.org/licenses/LICENSE-2.0 | |
* @website: http://www.improvely.com/ | |
*/ | |
!function ($) { | |
var DateRangePicker = function (element, options, cb) { | |
var hasOptions = typeof options == 'object' | |
var localeObject; | |
//state | |
this.startDate = Date.create('today'); | |
this.endDate = Date.create('today'); | |
this.minDate = false; | |
this.maxDate = false; | |
this.changed = false; | |
this.cleared = false; | |
this.ranges = {}; | |
this.opens = 'right'; | |
this.cb = function () { }; | |
this.format = '{MM}/{dd}/{yyyy}'; | |
this.separator = ' - '; | |
this.showWeekNumbers = false; | |
this.buttonClasses = ['btn-success']; | |
this.locale = { | |
applyLabel: 'Apply', | |
clearLabel:"Clear", | |
fromLabel: 'From', | |
toLabel: 'To', | |
weekLabel: 'W', | |
customRangeLabel: 'Custom Range', | |
daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr','Sa'], | |
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], | |
firstDay: 0 | |
}; | |
localeObject = this.locale; | |
this.leftCalendar = { | |
month: Date.create('today').set({ day: 1, month: this.startDate.getMonth(), year: this.startDate.getFullYear() }), | |
calendar: Array() | |
}; | |
this.rightCalendar = { | |
month: Date.create('today').set({ day: 1, month: this.endDate.getMonth(), year: this.endDate.getFullYear() }), | |
calendar: Array() | |
}; | |
//element that triggered the date range picker | |
this.element = $(element); | |
if (this.element.hasClass('pull-right')) | |
this.opens = 'left'; | |
if (this.element.is('input')) { | |
this.element.on({ | |
click: $.proxy(this.show, this), | |
focus: $.proxy(this.show, this) | |
}); | |
} else { | |
this.element.on('click', $.proxy(this.show, this)); | |
} | |
if (hasOptions) { | |
if(typeof options.locale == 'object') { | |
$.each(localeObject, function (property, value) { | |
localeObject[property] = options.locale[property] || value; | |
}); | |
} | |
} | |
var DRPTemplate = '<div class="daterangepicker dropdown-menu">' + | |
'<div class="calendar left"></div>' + | |
'<div class="calendar right"></div>' + | |
'<div class="ranges">' + | |
'<div class="range_inputs">' + | |
'<div class="daterangepicker_start_input" style="float: left">' + | |
'<label for="daterangepicker_start">' + this.locale.fromLabel + '</label>' + | |
'<input class="input-mini" type="text" name="daterangepicker_start" value="" disabled="disabled" />' + | |
'</div>' + | |
'<div class="daterangepicker_end_input" style="float: left; padding-left: 11px">' + | |
'<label for="daterangepicker_end">' + this.locale.toLabel + '</label>' + | |
'<input class="input-mini" type="text" name="daterangepicker_end" value="" disabled="disabled" />' + | |
'</div>' + | |
'<button class="btn btn-small btn-success applyBtn" disabled="disabled">' + this.locale.applyLabel + '</button> ' + | |
'<button class="btn btn-small clearBtn">' + this.locale.clearLabel + '</button>' + | |
'</div>' + | |
'</div>' + | |
'</div>'; | |
this.container = $(DRPTemplate).appendTo('body'); | |
if (hasOptions) { | |
if (typeof options.format == 'string') | |
this.format = options.format; | |
if (typeof options.separator == 'string') | |
this.separator = options.separator; | |
if (typeof options.startDate == 'string') | |
this.startDate = Date.create(options.startDate); | |
if (typeof options.endDate == 'string') | |
this.endDate = Date.create(options.endDate); | |
if (typeof options.minDate == 'string') | |
this.minDate = Date.create(options.minDate); | |
if (typeof options.maxDate == 'string') | |
this.maxDate = Date.create(options.maxDate); | |
if (typeof options.startDate == 'object') | |
this.startDate = options.startDate; | |
if (typeof options.endDate == 'object') | |
this.endDate = options.endDate; | |
if (typeof options.minDate == 'object') | |
this.minDate = options.minDate; | |
if (typeof options.maxDate == 'object') | |
this.maxDate = options.maxDate; | |
if (typeof options.ranges == 'object') { | |
for (var range in options.ranges) { | |
var start = options.ranges[range][0]; | |
var end = options.ranges[range][1]; | |
if (typeof start == 'string') | |
start = Date.create(start); | |
if (typeof end == 'string') | |
end = Date.create(end); | |
// If we have a min/max date set, bound this range | |
// to it, but only if it would otherwise fall | |
// outside of the min/max. | |
if (this.minDate && start < this.minDate) | |
start = this.minDate; | |
if (this.maxDate && end > this.maxDate) | |
end = this.maxDate; | |
// If the end of the range is before the minimum (if min is set) OR | |
// the start of the range is after the max (also if set) don't display this | |
// range option. | |
if ((this.minDate && end < this.minDate) || (this.maxDate && start > this.maxDate)) | |
{ | |
continue; | |
} | |
this.ranges[range] = [start, end]; | |
} | |
var list = '<ul>'; | |
for (var range in this.ranges) { | |
list += '<li>' + range + '</li>'; | |
} | |
list += '<li>' + this.locale.customRangeLabel + '</li>'; | |
list += '</ul>'; | |
this.container.find('.ranges').prepend(list); | |
} | |
// update day names order to firstDay | |
if (typeof options.locale == 'object') { | |
if (typeof options.locale.firstDay == 'number') { | |
this.locale.firstDay = options.locale.firstDay; | |
var iterator = options.locale.firstDay; | |
while (iterator > 0) { | |
this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); | |
iterator--; | |
} | |
} | |
} | |
if (typeof options.opens == 'string') | |
this.opens = options.opens; | |
if (typeof options.showWeekNumbers == 'boolean') { | |
this.showWeekNumbers = options.showWeekNumbers; | |
} | |
if (typeof options.buttonClasses == 'string') { | |
this.buttonClasses = [options.buttonClasses]; | |
} | |
if (typeof options.buttonClasses == 'object') { | |
this.buttonClasses = options.buttonClasses; | |
} | |
} | |
//apply CSS classes to buttons | |
var c = this.container; | |
$.each(this.buttonClasses, function (idx, val) { | |
c.find('button').addClass(val); | |
}); | |
if (this.opens == 'right') { | |
//swap calendar positions | |
var left = this.container.find('.calendar.left'); | |
var right = this.container.find('.calendar.right'); | |
left.removeClass('left').addClass('right'); | |
right.removeClass('right').addClass('left'); | |
} | |
if (typeof options == 'undefined' || typeof options.ranges == 'undefined') | |
this.container.find('.calendar').show(); | |
if (typeof cb == 'function') | |
this.cb = cb; | |
this.container.addClass('opens' + this.opens); | |
//event listeners | |
this.container.on('mousedown', $.proxy(this.mousedown, this)); | |
this.container.find('.calendar').on('click', '.prev', $.proxy(this.clickPrev, this)); | |
this.container.find('.calendar').on('click', '.next', $.proxy(this.clickNext, this)); | |
this.container.find('.ranges').on('click', 'button.applyBtn', $.proxy(this.clickApply, this)); | |
this.container.find('.ranges').on('click', 'button.clearBtn', $.proxy(this.clickClear, this)); | |
this.container.find('.calendar').on('click', 'td.available', $.proxy(this.clickDate, this)); | |
this.container.find('.calendar').on('mouseenter', 'td.available', $.proxy(this.enterDate, this)); | |
this.container.find('.calendar').on('mouseleave', 'td.available', $.proxy(this.updateView, this)); | |
this.container.find('.ranges').on('click', 'li', $.proxy(this.clickRange, this)); | |
this.container.find('.ranges').on('mouseenter', 'li', $.proxy(this.enterRange, this)); | |
this.container.find('.ranges').on('mouseleave', 'li', $.proxy(this.updateView, this)); | |
this.element.on('keyup', $.proxy(this.updateFromControl, this)); | |
this.updateView(); | |
this.updateCalendars(); | |
}; | |
DateRangePicker.prototype = { | |
constructor: DateRangePicker, | |
mousedown: function (e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
}, | |
updateView: function () { | |
this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); | |
this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); | |
this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format)); | |
this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format)); | |
if (this.startDate.is(this.endDate) || this.startDate.isBefore(this.endDate)) { | |
this.container.find('button.applyBtn').removeAttr('disabled'); | |
} else { | |
this.container.find('button.applyBtn').attr('disabled', 'disabled'); | |
} | |
}, | |
updateFromControl: function () { | |
if (!this.element.is('input')) return; | |
var dateString = this.element.val().split(this.separator); | |
var start = Date.create(dateString[0]); | |
var end = Date.create(dateString[1]); | |
if (start == null || end == null) return; | |
if (end.isBefore(start)) return; | |
this.startDate = start; | |
this.endDate = end; | |
this.updateView(); | |
this.cb(this.startDate, this.endDate); | |
this.updateCalendars(); | |
}, | |
notify: function () { | |
if (!this.cleared) { | |
this.updateView(); | |
} | |
if (this.element.is('input')) { | |
this.element.val(this.cleared ? '' : this.startDate.format(this.format) + this.separator + this.endDate.format(this.format)); | |
} | |
var arg1 = (this.cleared ? null : this.startDate), | |
arg2 = (this.cleared ? null : this.endDate); | |
this.cleared = false; | |
this.cb(arg1,arg2); | |
}, | |
move: function () { | |
if (this.opens == 'left') { | |
this.container.css({ | |
top: this.element.offset().top + this.element.outerHeight(), | |
right: $(window).width() - this.element.offset().left - this.element.outerWidth(), | |
left: 'auto' | |
}); | |
} else { | |
this.container.css({ | |
top: this.element.offset().top + this.element.outerHeight(), | |
left: this.element.offset().left, | |
right: 'auto' | |
}); | |
} | |
}, | |
show: function (e) { | |
this.container.show(); | |
this.move(); | |
if (e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
} | |
this.changed = false; | |
this.element.trigger('shown',{target:e.target,picker:this}); | |
$(document).on('mousedown', $.proxy(this.hide, this)); | |
}, | |
hide: function (e) { | |
this.container.hide(); | |
$(document).off('mousedown', this.hide); | |
if (this.changed) { | |
this.changed = false; | |
this.notify(); | |
} | |
}, | |
enterRange: function (e) { | |
var label = e.target.innerHTML; | |
if (label == this.locale.customRangeLabel) { | |
this.updateView(); | |
} else { | |
var dates = this.ranges[label]; | |
this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format)); | |
this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format)); | |
} | |
}, | |
clickRange: function (e) { | |
var label = e.target.innerHTML; | |
if (label == this.locale.customRangeLabel) { | |
this.container.find('.calendar').show(); | |
} else { | |
var dates = this.ranges[label]; | |
this.startDate = dates[0]; | |
this.endDate = dates[1]; | |
this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); | |
this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); | |
this.updateCalendars(); | |
this.changed = true; | |
this.container.find('.calendar').hide(); | |
this.hide(); | |
} | |
}, | |
clickPrev: function (e) { | |
var cal = $(e.target).parents('.calendar'); | |
if (cal.hasClass('left')) { | |
this.leftCalendar.month.addMonths(-1); | |
} else { | |
this.rightCalendar.month.addMonths(-1); | |
} | |
this.updateCalendars(); | |
}, | |
clickNext: function (e) { | |
var cal = $(e.target).parents('.calendar'); | |
if (cal.hasClass('left')) { | |
this.leftCalendar.month.addMonths(1); | |
} else { | |
this.rightCalendar.month.addMonths(1); | |
} | |
this.updateCalendars(); | |
}, | |
enterDate: function (e) { | |
var title = $(e.target).attr('title'); | |
var row = title.substr(1, 1); | |
var col = title.substr(3, 1); | |
var cal = $(e.target).parents('.calendar'); | |
if (cal.hasClass('left')) { | |
this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format)); | |
} else { | |
this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format)); | |
} | |
}, | |
clickDate: function (e) { | |
var title = $(e.target).attr('title'); | |
var row = title.substr(1, 1); | |
var col = title.substr(3, 1); | |
var cal = $(e.target).parents('.calendar'); | |
if (cal.hasClass('left')) { | |
startDate = this.leftCalendar.calendar[row][col]; | |
endDate = this.endDate; | |
this.element.trigger('clicked',{ | |
dir: 'left', | |
picker: this | |
}); | |
} else { | |
startDate = this.startDate; | |
endDate = this.rightCalendar.calendar[row][col]; | |
this.element.trigger('clicked',{ | |
dir: 'right', | |
picker: this | |
}); | |
} | |
cal.find('td').removeClass('active'); | |
if (startDate.is(endDate) || startDate.isBefore(endDate)) { | |
$(e.target).addClass('active'); | |
if (!startDate.is(this.startDate) || !endDate.is(this.endDate)) | |
this.changed = true; | |
this.startDate = startDate; | |
this.endDate = endDate; | |
} | |
else if (startDate.isAfter(endDate)) { | |
$(e.target).addClass('active'); | |
this.changed = true; | |
this.startDate = startDate; | |
this.endDate = startDate.clone().addDays(1); | |
} | |
this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); | |
this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); | |
this.updateCalendars(); | |
}, | |
clickApply: function (e) { | |
this.hide(); | |
}, | |
clickClear: function (e) { | |
this.changed = true; | |
this.cleared = true; | |
this.hide(); | |
}, | |
updateCalendars: function () { | |
this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.getMonth(), this.leftCalendar.month.getFullYear()); | |
this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.getMonth(), this.rightCalendar.month.getFullYear()); | |
this.container.find('.calendar.left').html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate)); | |
this.container.find('.calendar.right').html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, this.startDate, this.maxDate)); | |
this.element.trigger('updated',this); | |
}, | |
buildCalendar: function (month, year) { | |
var firstDay = Date.create('today').set({ day: 1, month: month, year: year }); | |
var lastMonth = firstDay.clone().addDays(-1).getMonth(); | |
var lastYear = firstDay.clone().addDays(-1).getFullYear(); | |
var daysInMonth = this.getDaysInMonth(year, month); | |
var daysInLastMonth = this.getDaysInMonth(lastYear, lastMonth); | |
var dayOfWeek = firstDay.getDay(); | |
//initialize a 6 rows x 7 columns array for the calendar | |
var calendar = Array(); | |
for (var i = 0; i < 6; i++) { | |
calendar[i] = Array(); | |
} | |
//populate the calendar with date objects | |
var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; | |
if (startDay > daysInLastMonth) | |
startDay -= 7; | |
if (dayOfWeek == this.locale.firstDay) | |
startDay = daysInLastMonth - 6; | |
var curDate = Date.create('today').set({ day: startDay, month: lastMonth, year: lastYear }); | |
for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = curDate.clone().addDays(1)) { | |
if (i > 0 && col % 7 == 0) { | |
col = 0; | |
row++; | |
} | |
calendar[row][col] = curDate; | |
} | |
return calendar; | |
}, | |
renderCalendar: function (calendar, selected, minDate, maxDate) { | |
var html = '<table class="table-condensed">'; | |
html += '<thead>'; | |
html += '<tr>'; | |
// add empty cell for week number | |
if (this.showWeekNumbers) | |
html += '<th></th>'; | |
if (!minDate || minDate < calendar[1][1]) | |
{ | |
html += '<th class="prev available"><i class="icon-arrow-left"></i></th>'; | |
} | |
else | |
{ | |
html += '<th></th>'; | |
} | |
html += '<th colspan="5" style="width: auto">' + this.locale.monthNames[calendar[1][1].getMonth()] + calendar[1][1].format(' {yyyy}') + '</th>'; | |
if (!maxDate || maxDate > calendar[1][1]) | |
{ | |
html += '<th class="next available"><i class="icon-arrow-right"></i></th>'; | |
} | |
else | |
{ | |
html += '<th></th>'; | |
} | |
html += '</tr>'; | |
html += '<tr>'; | |
// add week number label | |
if (this.showWeekNumbers) | |
html += '<th class="week">' + this.locale.weekLabel + '</th>'; | |
$.each(this.locale.daysOfWeek, function (index, dayOfWeek) { | |
html += '<th>' + dayOfWeek + '</th>'; | |
}); | |
html += '</tr>'; | |
html += '</thead>'; | |
html += '<tbody>'; | |
for (var row = 0; row < 6; row++) { | |
html += '<tr>'; | |
// add week number | |
if (this.showWeekNumbers) | |
html += '<td class="week">' + calendar[row][0].getWeek() + '</td>'; | |
for (var col = 0; col < 7; col++) { | |
var cname = 'available '; | |
cname += (calendar[row][col].getMonth() == calendar[1][1].getMonth()) ? '' : 'off'; | |
// Normalise the time so the comparison won't fail | |
selected.setHours(0,0,0,0); | |
if ( (minDate && calendar[row][col] < minDate) || (maxDate && calendar[row][col] > maxDate)) | |
{ | |
cname = ' off disabled '; | |
} | |
else if (calendar[row][col].is(selected)) | |
{ | |
cname += ' active '; | |
if (calendar[row][col].is(this.startDate)) { cname += ' start-date '; } | |
if (calendar[row][col].is(this.endDate)) { cname += ' end-date '; } | |
} | |
else if (calendar[row][col] >= this.startDate && calendar[row][col] <= this.endDate) | |
{ | |
cname += ' in-range '; | |
if (calendar[row][col].is(this.startDate)) { cname += ' start-date '; } | |
if (calendar[row][col].is(this.endDate)) { cname += ' end-date '; } | |
} | |
var title = 'r' + row + 'c' + col; | |
html += '<td class="' + cname.replace(/\s+/g,' ').replace(/^\s?(.*?)\s?$/,'$1') + '" title="' + title + '">' + calendar[row][col].getDate() + '</td>'; | |
} | |
html += '</tr>'; | |
} | |
html += '</tbody>'; | |
html += '</table>'; | |
return html; | |
}, | |
getDaysInMonth: function (y, m) { | |
return /8|3|5|10/.test(--m)?30:m==1?(!(y%4)&&y%100)||!(y%400)?29:28:31; | |
} | |
}; | |
$.fn.daterangepicker = function (options, cb) { | |
this.each(function() { | |
var el = $(this); | |
if (!el.data('daterangepicker')) | |
el.data('daterangepicker', new DateRangePicker(el, options, cb)); | |
}); | |
return this; | |
}; | |
} (window.jQuery); | |
build | |
.vimrc | |
*.swp | |
*.swm | |
*.swo | |
*.vim | |
.jhw-cache | |
node_modules | |
dev | |
Copyright (c) 2012 Carl Sutherland | |
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. | |
all: test flotr2 | |
test: | |
cd spec; jasmine-headless-webkit -j jasmine.yml -c | |
libraries: | |
smoosh make/lib.json | |
cat ./build/bean.js > build/lib.js | |
cat ./build/underscore.js >> build/lib.js | |
cat ./build/bean.min.js > build/lib.min.js | |
echo ";" >> build/lib.min.js | |
cat ./build/underscore.min.js >> build/lib.min.js | |
echo ";" >> build/lib.min.js | |
ie: | |
smoosh make/ie.json | |
flotr2: libraries ie | |
smoosh make/flotr2.json | |
cat build/lib.js build/flotr2.js > flotr2.js | |
cat build/lib.min.js > flotr2.min.js | |
cat build/flotr2.min.js >> flotr2.min.js | |
echo ';' >> flotr2.min.js | |
cp build/ie.min.js flotr2.ie.min.js | |
flotr2-basic: libraries ie | |
smoosh make/basic.json | |
cat build/lib.min.js > flotr2-basic.min.js | |
cat build/flotr2-basic.min.js >> flotr2-basic.min.js | |
flotr-examples: | |
smoosh make/examples.json | |
cp build/examples.min.js flotr2.examples.min.js | |
cp build/examples-types.js flotr2.examples.types.js | |
flotr-amd: flotr2 | |
cat js/amd/pre.js > flotr2.amd.js | |
cat build/flotr2.js >> flotr2.amd.js | |
cat js/amd/post.js >> flotr2.amd.js | |
Flotr2 | |
====== | |
The Canvas graphing library. | |
![Google Groups](http://groups.google.com/intl/en/images/logos/groups_logo_sm.gif) | |
http://groups.google.com/group/flotr2/ | |
Please fork http://jsfiddle.net/cesutherland/ZFBj5/ with your question or bug reproduction case. | |
API | |
--- | |
The API consists of a primary draw method which accepts a configuration object, helper methods, and several microlibs. | |
### Example | |
```javascript | |
var | |
// Container div: | |
container = document.getElementById("flotr-example-graph"), | |
// First data series: | |
d1 = [[0, 3], [4, 8], [8, 5], [9, 13]], | |
// Second data series: | |
d2 = [], | |
// A couple flotr configuration options: | |
options = { | |
xaxis: { | |
minorTickFreq: 4 | |
}, | |
grid: { | |
minorVerticalLines: true | |
} | |
}, | |
i, graph; | |
// Generated second data set: | |
for (i = 0; i < 14; i += 0.5) { | |
d2.push([i, Math.sin(i)]); | |
} | |
// Draw the graph: | |
graph = Flotr.draw( | |
container, // Container element | |
[ d1, d2 ], // Array of data series | |
options // Configuration options | |
); | |
``` | |
### Microlibs | |
* [underscore.js](http://documentcloud.github.com/underscore/) | |
* [bean.js](https://github.com/fat/bean) | |
Extending | |
--------- | |
Flotr may be extended by adding new plugins and graph types. | |
### Graph Types | |
Graph types define how a particular chart is rendered. Examples include line, bar, pie. | |
Existing graph types are found in `js/types/`. | |
### Plugins | |
Plugins extend the core of flotr with new functionality. They can add interactions, new decorations, etc. Examples | |
include titles, labels and selection. | |
The plugins included are found in `js/plugins/`. | |
Development | |
----------- | |
This project uses [smoosh](https://github.com/fat/smoosh) to build and [jasmine](http://pivotal.github.com/jasmine/) | |
with [js-imagediff](https://github.com/HumbleSoftware/js-imagediff) to test. Tests may be executed by | |
[jasmine-headless-webkit](http://johnbintz.github.com/jasmine-headless-webkit/) with | |
`cd spec; jasmine-headless-webkit -j jasmine.yml -c` or by a browser by navigating to | |
`flotr2/spec/SpecRunner.html`. | |
Shoutouts | |
--------- | |
Thanks to Bas Wenneker, Fabien Ménager and others for all the work on the original Flotr. | |
Thanks to Jochen Berger and Jordan Santell for their contributions to Flotr2. | |
Flotr 2 Architecture Notes | |
Global: | |
====== | |
Flotr.js - | |
versioning information | |
browser detection | |
extension (plugins, graph types) | |
draw | |
clone / merge | |
tick size | |
tick formatter | |
engineering notation | |
magnitude | |
rad, pixel, floor | |
drawText | |
measureText | |
getBestTextAlign | |
align map | |
compatibility | |
Graph Architecture: | |
=================== | |
Axis - | |
all series | |
orientation | |
ticks (major, minor) | |
scale (d2p, p2d, logarithmic) | |
notion of stacks | |
Series - | |
per 'data' | |
notion of range (x, y, min, max) | |
Graph - | |
DOM constructon | |
event attachment | |
options initialization | |
data range calculations | |
canvas spacing calculations | |
event normalization | |
draw methods | |
DOM cleanup | |
event cleanup | |
Utilities: | |
========== | |
Color | |
build colors | |
parse textual color data | |
convert colors | |
clone colors | |
Text | |
calculate text size | |
canvas size | |
html size | |
Date | |
formatting | |
constants | |
Spacing Calculation | |
=================== | |
Flotr | |
calculate data | |
calculate margins | |
Chart | |
calculate Data Ranges - Explicit or auto data minimum, maximums | |
calculate Data Range Extensions - By chart type, extend data range with needs of chart type (ie. stacked bars, stacked lines) | |
add Chart Padding - By chart type | |
Text | |
use explicit margins | |
calculate label margins | |
calculate title margins | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | |
<title>Flotr Example Index Page</title> | |
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css" type="text/css" /> | |
<link rel="stylesheet" href="examples.css" type="text/css" /> | |
<link rel="stylesheet" href="editor.css" type="text/css" /> | |
</head> | |
<body> | |
<div id="body-container"> | |
<div id="content-container"> | |
<div id="content"> | |
<div id="examples"></div> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script type="text/javascript" src="../lib/yepnope.js"></script> | |
<script type="text/javascript" src="js/includes.dev.js"></script> | |
</html> | |
/* Editor */ | |
.editor { | |
position: relative; | |
} | |
.editor .render { | |
height: 240px; | |
width: 320px; | |
margin: 8px auto; | |
} | |
.editor .source { | |
border: 1px solid #ddd; | |
border-radius: 3px; | |
} | |
.editor .controls { | |
position: absolute;; | |
z-index: 100; | |
right: 8px; | |
margin-top: -12px; | |
} | |
.editor .controls button { | |
float: right; | |
} | |
.editor .errors { | |
color: #ee0000; | |
padding: 8px; | |
font-size: 12px; | |
background: #fee; | |
border-bottom: 1px solid #eee; | |
} | |
.editor .errors .error { | |
font-weight: bold | |
} | |
.editor .errors .message { | |
font-style: italic; | |
} | |
.editor .errors .position { | |
display: block; | |
margin-top: 4px; | |
} | |
.editor.no-run .controls, | |
.editor.no-run .render { | |
display: none; | |
} | |
/* html type */ | |
.editor.html .render { | |
height: 400px; | |
width: 800px; | |
text-align: center; | |
} | |
.editor.html .render iframe { | |
height: 100%; | |
width: 100%; | |
border: none; | |
} | |
/* CodeMirror */ | |
.CodeMirror { | |
background: #fafafa; | |
} | |
.CodeMirror.CodeMirror-focused { | |
} | |
.CodeMirror-scroll { | |
height: auto; | |
overflow: visible; | |
overflow-x: auto; | |
} | |
.CodeMirror-lines pre, | |
.CodeMirror-gutter pre { | |
line-height: 16px; | |
} | |
body { | |
font-family : sans-serif; | |
padding: 0px; | |
margin: 0px; | |
} | |
/* Example */ | |
.flotr-example { | |
display: none; | |
margin: 0px auto 48px auto; | |
position: relative; | |
} | |
.flotr-example-label { | |
font-size: 18px; | |
padding: 14px 0px; | |
} | |
.flotr-example-editor .editor .render { | |
width: 600px; | |
height: 400px; | |
margin: 12px auto 18px auto; | |
} | |
.flotr-example-editor .editor .source { | |
width: 720px; | |
} | |
/* Chart no-select */ | |
.flotr-example-editor .editor .render, | |
.flotr-examples-thumb { | |
-webkit-user-select: none; | |
-khtml-user-select: none; | |
-moz-user-select: none; | |
-o-user-select: none; | |
user-select: none; | |
} | |
/* Examples */ | |
.flotr-examples-thumbs { | |
text-align: center; | |
} | |
.flotr-examples-reset { | |
z-index: 100; | |
cursor: pointer; | |
text-decoration: underline; | |
position: absolute; | |
top: 260px; | |
right: 24px; | |
display: none; | |
} | |
.flotr-examples-collapsed .flotr-examples-reset { | |
display: block; | |
} | |
.flotr-examples-thumb { | |
display: inline-block; | |
font-size : 11px; | |
width : 300px; | |
height : 200px; | |
margin: 10px 15px; | |
border: 2px solid transparent; | |
} | |
.flotr-examples-thumb.flotr-examples-highlight{ | |
font-size : 12px; | |
width : 330px; | |
height : 220px; | |
margin: 0px 0px; | |
} | |
.flotr-examples-thumb .flotr-legend, | |
.flotr-examples-thumb .flotr-mouse-value { | |
display : none; | |
} | |
.flotr-examples-collapsed .flotr-examples-container { | |
margin-top: 20px; | |
position: relative; | |
margin: 0px auto; | |
} | |
.flotr-examples-collapsed .flotr-examples-thumbs { | |
position: relative; | |
overflow-x: auto; | |
white-space: nowrap; | |
} | |
/* Flotr Styles */ | |
.flotr-datagrid-container { | |
border: 1px solid #999; | |
border-bottom: none; | |
background: #fff; | |
} | |
.flotr-datagrid { | |
border-collapse: collapse; | |
border-spacing: 0; | |
} | |
.flotr-datagrid td, .flotr-datagrid th { | |
border: 1px solid #ccc; | |
padding: 1px 3px; | |
min-width: 2em; | |
} | |
.flotr-datagrid tr:hover, .flotr-datagrid col.hover { | |
background: #f3f3f3; | |
} | |
.flotr-datagrid tr:hover th, .flotr-datagrid th.hover { | |
background: #999; | |
color: #fff; | |
} | |
.flotr-datagrid th { | |
text-align: left; | |
background: #e3e3e3; | |
border: 2px outset #fff; | |
} | |
.flotr-datagrid-toolbar { | |
padding: 1px; | |
border-bottom: 1px solid #ccc; | |
background: #f9f9f9; | |
} | |
.flotr-datagrid td:hover { | |
background: #ccc; | |
} | |
.flotr-datagrid .first-row th { | |
text-align: center; | |
} | |
.flotr-canvas { | |
margin-bottom: -3px; | |
padding-bottom: 1px; | |
} | |
.flotr-tabs-group { | |
border-top: 1px solid #999; | |
} | |
.flotr-tab { | |
border: 1px solid #666; | |
border-top: none; | |
margin: 0 3px; | |
padding: 1px 4px; | |
cursor: pointer; | |
-moz-border-radius: 0 0 4px 4px; | |
-webkit-border-bottom-left-radius: 4px; | |
-webkit-border-bottom-right-radius: 4px; | |
border-radius: 0 0 4px 4px; | |
opacity: 0.5; | |
-moz-opacity: 0.5; | |
} | |
.flotr-tab.selected { | |
background: #ddd; | |
opacity: 1; | |
-moz-opacity: 1; | |
} | |
.flotr-tab:hover { | |
background: #ccc; | |
} | |
/* Large */ | |
.flotr-examples-large .flotr-example { | |
width: 1360px; | |
margin: 0px auto; | |
position: relative; | |
} | |
.flotr-examples-large .flotr-example-editor .editor .render { | |
margin-left: 0px; | |
margin-right: 0px; | |
} | |
.flotr-examples-large .flotr-example-editor .controls { | |
top: 0px; | |
} | |
.flotr-examples-large .flotr-example-editor .source { | |
position: absolute; | |
top: 0px; | |
right: 0px; | |
} | |
/* Veritical Thumbs */ | |
.flotr-examples-large.flotr-examples-collapsed .flotr-examples-reset, | |
.flotr-examples-medium.flotr-examples-collapsed .flotr-examples-reset { | |
top: 16px; | |
} | |
.flotr-examples-large.flotr-examples-collapsed .flotr-examples-thumbs, | |
.flotr-examples-medium.flotr-examples-collapsed .flotr-examples-thumbs { | |
position: fixed; | |
width: 400px; | |
left: 0px; | |
top: 0px; | |
overflow-y: auto; | |
background: #fff; | |
} | |
.flotr-examples-large.flotr-examples-collapsed .flotr-examples-thumb, | |
.flotr-examples-medium.flotr-examples-collapsed .flotr-examples-thumb { | |
display: block; | |
float: center; | |
margin: 10px auto; | |
} | |
.flotr-examples-large.flotr-examples-collapsed .flotr-examples-container, | |
.flotr-examples-medium.flotr-examples-collapsed .flotr-examples-container { | |
margin-left: 400px; | |
} | |
/* Vertical Example */ | |
.flotr-examples-small .flotr-example, | |
.flotr-examples-medium .flotr-example { | |
width: 720px; | |
} | |
.flotr-examples-small .flotr-example-editor .source, | |
.flotr-examples-medium .flotr-example-editor .source { | |
position: relative; | |
} | |
Binary files /dev/null and b/js/flotr2/examples/images/butterfly.jpg differ
Binary files /dev/null and b/js/flotr2/examples/images/checkmark.png differ
Binary files /dev/null and b/js/flotr2/examples/images/xmark.png differ
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> | |
<title>Flotr Example Index Page</title> | |
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css" type="text/css" /> | |
<link rel="stylesheet" href="examples.css" type="text/css" /> | |
<link rel="stylesheet" href="editor.css" type="text/css" /> | |
</head> | |
<body> | |
<div id="body-container"> | |
<div id="content-container"> | |
<div id="content"> | |
<div id="examples"></div> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script type="text/javascript" src="../lib/yepnope.js"></script> | |
<script type="text/javascript" src="js/includes.min.js"></script> | |
</html> | |
(function () { | |
var | |
ONERROR = window.onerror, | |
COUNT = 0, | |
TYPES = {}, | |
T_CONTROLS = | |
'<div class="controls">' + | |
'<button class="fiddle btn large primary">Fiddle</button>' + | |
'<button class="run btn large primary">Run</button>' + | |
'</div>', | |
T_EDITOR = '<div class="editor"></div>', | |
T_SOURCE = '<div class="source"></div>', | |
T_ERRORS = '<div class="errors"></div>', | |
T_RENDER = '<div class="render"></div>', | |
T_IFRAME = '<iframe></iframe>'; | |
// Javascript type: | |
TYPES.javascript = function Javascript (o) { | |
this.onerror = o.onerror; | |
}; | |
TYPES.javascript.prototype = { | |
codeMirrorType : 'javascript', | |
example : function (o) { | |
var | |
example = o.example, | |
render = o.render, | |
renderId = $(render).attr('id'), | |
args = o.args ? ',' + o.args.toString() : ''; | |
return '(' + example + ')(document.getElementById("' + renderId+ '")' + | |
args + ');'; | |
}, | |
render : function (o) { | |
eval(o.example); | |
} | |
}; | |
// HTML Type: | |
TYPES.html = function Html (o) { | |
this.onerror = o.onerror; | |
}; | |
TYPES.html.prototype = { | |
codeMirrorType : 'htmlmixed', | |
example : function (o) { | |
return $.trim(o.example); | |
}, | |
render : function (o) { | |
var | |
example = o.example, | |
render = o.render, | |
iframe = $(T_IFRAME), | |
that = this, | |
win, doc; | |
render.html(iframe); | |
win = iframe[0].contentWindow; | |
doc = win.document; | |
doc.open(); | |
// Error | |
win.onerror = iframe.onerror = function () { | |
that.onerror.apply(null, arguments); | |
} | |
doc.write(example); | |
doc.close(); | |
} | |
}; | |
// Editor | |
function Editor (container, o) { | |
var | |
type = o.type || 'javascript', | |
example = o.example || '', | |
noRun = o.noRun || false, | |
teardown = o.teardown || false, | |
controls = $(T_CONTROLS), | |
render = $(T_RENDER), | |
errors = $(T_ERRORS), | |
source = $(T_SOURCE), | |
node = $(T_EDITOR), | |
renderId = 'editor-render-' + COUNT, | |
api, | |
render, | |
codeMirror; | |
api = new TYPES[type]({ | |
onerror : onerror | |
}); | |
if (!api) throw 'Invalid type: API not found for type `' + type + '`.'; | |
render | |
.attr('id', renderId); | |
errors | |
.hide(); | |
node | |
.append(render) | |
.append(controls) | |
.append(source) | |
.addClass(type) | |
.addClass(noRun ? 'no-run' : ''); | |
container = $(container); | |
container | |
.append(node); | |
source | |
.append(errors) | |
example = api.example({ | |
args : o.args, | |
example : example, | |
render : render | |
}); | |
codeMirror = CodeMirror(source[0], { | |
value : example, | |
readOnly : noRun, | |
lineNumbers : true, | |
mode : api.codeMirrorType | |
}); | |
if (!noRun) { | |
controls.delegate('.run', 'click', function () { | |
example = codeMirror.getValue(); | |
execute(); | |
}); | |
execute(); | |
} | |
controls.delegate('.fiddle', 'click', function () { | |
fiddle(); | |
}); | |
// Error handling: | |
window.onerror = function (message, url, line) { | |
onerror(message, url, line); | |
console.log(message); | |
if (ONERROR && $.isFunction(ONERROR)) { | |
return ONERROR(message, url, line); | |
} else { | |
return false; | |
} | |
} | |
// Helpers | |
function execute () { | |
errors.hide(); | |
if (teardown) { | |
teardown.call(); | |
} | |
api.render({ | |
example : example, | |
render : render | |
}); | |
} | |
function onerror (message, url, line) { | |
// @TODO Find some js error normalizing lib | |
var | |
doThatSexyThang = false, | |
html = '<span class="error">Error: </span>', | |
error, stack; | |
/* | |
// Native error type handling: | |
if (typeof (message) !== 'string') { | |
error = message; | |
message = error.message; | |
stack = error.stack; | |
//if (stack) { | |
console.log(stack); | |
//} | |
//console.log(message); | |
} | |
*/ | |
html += '<span class="message">' + message + '</span>'; | |
if (typeof (line) !== "undefined") { | |
html += '<span class="position">'; | |
html += 'Line <span class="line">' + line + '</span>'; | |
console.log(url); | |
if (url) { | |
html += ' of '; | |
if (url == window.location) { | |
html += '<span class="url">script</span>'; | |
if (doThatSexyThang) { | |
//codeMirror.setMarker(line, '•'); | |
} | |
} else { | |
html += '<span class="url">' + url + '</span>'; | |
} | |
} | |
html += '.</span>'; | |
} | |
errors.show(); | |
errors.html(html); | |
} | |
function fiddle () { | |
var | |
url = 'http://jsfiddle.net/api/post/jquery/1.7/', | |
form = $('<form method="post" action="' + url + '" target="_blank"></form>'), | |
input; | |
// Resources | |
resources = [ | |
'https://raw.github.com/HumbleSoftware/Flotr2/master/flotr2.min.js', | |
'https://raw.github.com/HumbleSoftware/Flotr2/master/examples/examples.css' | |
]; | |
input = $('<input type="hidden" name="resources">') | |
.attr('value', resources.join(',')); | |
form.append(input); | |
// HTML | |
input = $('<input type="hidden" name="html">') | |
.attr('value', '<div id="'+renderId+'"></div>'); | |
form.append(input); | |
// CSS | |
input = $('<input type="hidden" name="normalize_css" value="no">') | |
form.append(input); | |
input = $('<input type="hidden" name="css">') | |
.attr('value', | |
'#'+renderId+' {\n width: 340px;\n height: 220px;' + | |
'\n margin: 24px auto;\n}' | |
); | |
form.append(input); | |
// JS | |
input = $('<input type="hidden" name="js">') | |
.attr('value', '$(function () {\n' + example + '\n});'); | |
form.append(input); | |
// Submit | |
form.append(input); | |
$(document.body).append(form); | |
form.submit(); | |
} | |
COUNT++; | |
this.setExample = function (source, args) { | |
example = api.example({ | |
args : args, | |
example : source, | |
render : render | |
}); | |
codeMirror.setValue(example); | |
codeMirror.refresh(); | |
execute(); | |
} | |
} | |
if (typeof Flotr.Examples === 'undefined') Flotr.Examples = {}; | |
Flotr.Examples.Editor = Editor; | |
})(); | |
(function () { | |
var | |
_ = Flotr._, | |
DOT = '.', | |
CN_EXAMPLE = 'flotr-example', | |
CN_LABEL = 'flotr-example-label', | |
CN_TITLE = 'flotr-example-title', | |
CN_MARKUP = 'flotr-example-description', | |
CN_EDITOR = 'flotr-example-editor', | |
ID_GRAPH = 'flotr-example-graph', | |
TEMPLATE = '' + | |
'<div class="' + CN_EXAMPLE + '">' + | |
'<div class="' + CN_LABEL + ' ' + CN_TITLE + '"></div>' + | |
'<div class="' + CN_MARKUP + '"></div>' + | |
'<div class="' + CN_EDITOR + '"></div>' + | |
'</div>', | |
Example = function (o) { | |
this.options = o; | |
this.example = null; | |
this._initNodes(); | |
}; | |
Example.prototype = { | |
setExample : function (example) { | |
var | |
source = this.getSource(example), | |
editorNode = this._editorNode; | |
this.example = example; | |
Math.seedrandom(example.key); | |
this._exampleNode.css({ display: 'block' }); | |
this._titleNode.html(example.name || ''); | |
this._markupNode.html(example.description || ''); | |
if (!this._editor) { | |
this._editor = new Flotr.Examples.Editor(editorNode, { | |
args : example.args, | |
example : source, | |
teardown : function () { | |
// Unbind event listeners from previous examples | |
Flotr.EventAdapter.stopObserving($(editorNode).find('.render')[0]); | |
$(editorNode).find('canvas').each(function (index, canvas) { | |
Flotr.EventAdapter.stopObserving(canvas); | |
}); | |
} | |
}); | |
} else { | |
this._editor.setExample(source, example.args); | |
} | |
}, | |
getSource : function (example) { | |
var | |
source = example.callback.toString(); | |
// Hack for FF code style | |
if (navigator.userAgent.search(/firefox/i) !== -1) | |
source = js_beautify(source); | |
return source; | |
}, | |
executeCallback : function (example, node) { | |
if (!_.isElement(node)) node = node[0]; | |
var args = (example.args ? [node].concat(example.args) : [node]); | |
Math.seedrandom(example.key); | |
return example.callback.apply(this, args); | |
}, | |
_initNodes : function () { | |
var | |
node = this.options.node, | |
example = $(TEMPLATE); | |
this._titleNode = example.find(DOT + CN_TITLE); | |
this._markupNode = example.find(DOT + CN_MARKUP); | |
this._editorNode = example.find(DOT + CN_EDITOR); | |
this._exampleNode = example; | |
node.append(example); | |
} | |
}; | |
Flotr.Examples.Example = Example; | |
})(); | |
(function () { | |
var ExampleList = function () { | |
// Map of examples. | |
this.examples = {}; | |
}; | |
ExampleList.prototype = { | |
add : function (example) { | |
this.examples[example.key] = example; | |
}, | |
get : function (key) { | |
return key ? (this.examples[key] || null) : this.examples; | |
}, | |
getType : function (type) { | |
return Flotr._.select(this.examples, function (example) { | |
return (example.type === type); | |
}); | |
} | |
} | |
Flotr.ExampleList = new ExampleList(); | |
})(); | |
(function () { | |
var | |
E = Flotr.EventAdapter, | |
_ = Flotr._, | |
CLICK = 'click', | |
EXAMPLE = 'example', | |
MOUSEENTER = 'mouseenter', | |
MOUSELEAVE = 'mouseleave', | |
DOT = '.', | |
CN_EXAMPLES = 'flotr-examples', | |
CN_CONTAINER = 'flotr-examples-container', | |
CN_RESET = 'flotr-examples-reset', | |
CN_THUMBS = 'flotr-examples-thumbs', | |
CN_THUMB = 'flotr-examples-thumb', | |
CN_COLLAPSED = 'flotr-examples-collapsed', | |
CN_HIGHLIGHT = 'flotr-examples-highlight', | |
CN_LARGE = 'flotr-examples-large', | |
CN_MEDIUM = 'flotr-examples-medium', | |
CN_SMALL = 'flotr-examples-small', | |
CN_MOBILE = 'flotr-examples-mobile', | |
T_THUMB = '<div class="' + CN_THUMB + '"></div>', | |
TEMPLATE = '' + | |
'<div class="' + CN_EXAMPLES + '">' + | |
'<div class="' + CN_RESET + '">View All</div>' + | |
'<div class="' + CN_THUMBS + '"></div>' + | |
'<div class="' + CN_CONTAINER + '"></div>' + | |
'</div>' | |
Examples = function (o) { | |
if (_.isUndefined(Flotr.ExampleList)) throw "Flotr.ExampleList not defined."; | |
this.options = o; | |
this.list = Flotr.ExampleList; | |
this.current = null; | |
this.single = false; | |
this._initNodes(); | |
this._example = new Flotr.Examples.Example({ | |
node : this._exampleNode | |
}); | |
//console.time(EXAMPLE); | |
//console.profile(); | |
this._initExamples(); | |
//console.profileEnd(); | |
//console.timeEnd(EXAMPLE); | |
}; | |
Examples.prototype = { | |
examples : function () { | |
var | |
styles = {cursor : 'pointer'}, | |
thumbsNode = this._thumbsNode, | |
list = this.list.get(), | |
that = this; | |
var | |
order = [ | |
"basic", | |
"basic-axis", | |
"basic-bars", | |
"basic-bars-horizontal", | |
"basic-bar-stacked", | |
"basic-stacked-horizontal", | |
"basic-pie", | |
"basic-radar", | |
"basic-bubble", | |
"basic-candle", | |
"basic-legend", | |
"mouse-tracking", | |
"mouse-zoom", | |
"mouse-drag", | |
"basic-time", | |
"negative-values", | |
"click-example", | |
"download-image", | |
"download-data", | |
"advanced-titles", | |
"color-gradients", | |
"basic-timeline", | |
"advanced-markers" | |
]; | |
(function runner () { | |
var | |
key = order.shift(), | |
example = list[key]; | |
if (example.type === 'profile' || example.type === 'test') return; | |
var node = $(T_THUMB); | |
node.data('example', example); | |
thumbsNode.append(node); | |
that._example.executeCallback(example, node); | |
node.click(function () {that._loadExample(example)}); | |
if (order.length) setTimeout(runner, 20); | |
})(); | |
function zoomHandler (e) { | |
var | |
node = $(e.currentTarget), | |
example = node.data('example'), | |
orientation = e.data.orientation; | |
if (orientation ^ node.hasClass(CN_HIGHLIGHT)) { | |
node.toggleClass(CN_HIGHLIGHT).css(styles); | |
that._example.executeCallback(example, node); | |
} | |
} | |
thumbsNode.delegate(DOT + CN_THUMB, 'mouseenter', {orientation : true}, zoomHandler); | |
thumbsNode.delegate(DOT + CN_THUMB, 'mouseleave', {orientation : false}, zoomHandler); | |
if ($(window).hashchange) { | |
$(window).hashchange(function () { | |
that._loadHash(); | |
}); | |
} | |
}, | |
_loadExample : function (example) { | |
if (example) { | |
if (this._currentExample !== example) { | |
this._currentExample = example; | |
} else { | |
return; | |
} | |
window.location.hash = '!'+(this.single ? 'single/' : '')+example.key; | |
if (!scroller) { | |
this._thumbsNode.css({ | |
position: 'absolute', | |
height: '0px', | |
overflow: 'hidden', | |
width: '0px' | |
}); | |
this._resetNode.css({ | |
top: '16px' | |
}); | |
} | |
this._examplesNode.addClass(CN_COLLAPSED); | |
this._exampleNode.show(); | |
this._example.setExample(example); | |
this._resize(); | |
$(document).scrollTop(0); | |
} | |
}, | |
_reset : function () { | |
window.location.hash = ''; | |
if (!scroller) { | |
this._thumbsNode.css({ | |
position: '', | |
height: '', | |
overflow: '', | |
width: '' | |
}); | |
} | |
this._examplesNode.removeClass(CN_COLLAPSED); | |
this._thumbsNode.height(''); | |
this._exampleNode.hide(); | |
}, | |
_initNodes : function () { | |
var | |
node = $(this.options.node), | |
that = this, | |
examplesNode = $(TEMPLATE); | |
that._resetNode = examplesNode.find(DOT+CN_RESET); | |
that._exampleNode = examplesNode.find(DOT+CN_CONTAINER); | |
that._thumbsNode = examplesNode.find(DOT+CN_THUMBS); | |
that._examplesNode = examplesNode; | |
that._resetNode.click(function () { | |
that._reset(); | |
}); | |
node.append(examplesNode); | |
this._initResizer(); | |
}, | |
_initResizer : function () { | |
var | |
that = this, | |
node = that._examplesNode, | |
page = $(window), | |
currentClass; | |
$(window).resize(applySize); | |
applySize(); | |
function applySize () { | |
var | |
height = page.height() - (that.options.thumbPadding || 0), | |
width = page.width(), | |
newClass; | |
if (width > 1760) { | |
newClass = CN_LARGE; | |
that._thumbsNode.height(height); | |
} else if (width > 1140) { | |
newClass = CN_MEDIUM; | |
that._thumbsNode.height(height); | |
} else { | |
newClass = CN_SMALL; | |
that._thumbsNode.height(''); | |
} | |
if (currentClass !== newClass) { | |
if (currentClass) | |
that._examplesNode.removeClass(currentClass); | |
that._examplesNode.addClass(newClass); | |
currentClass = newClass; | |
} | |
} | |
this._resize = applySize; | |
}, | |
_initExamples : function () { | |
var | |
hash = window.location.hash, | |
example, params; | |
hash = hash.substring(2); | |
params = hash.split('/'); | |
if (params.length == 1) { | |
this.examples(); | |
if (hash) { | |
this._loadHash(); | |
} | |
} | |
else { | |
if (params[0] == 'single') { | |
this.single = true; | |
this._loadExample( | |
this.list.get(params[1]) | |
); | |
} | |
} | |
}, | |
_loadHash : function () { | |
var | |
hash = window.location.hash, | |
example; | |
hash = hash.substring(2); | |
if (hash) { | |
example = this.list.get(hash); | |
this._loadExample(example); | |
} else { | |
this._reset(); | |
} | |
} | |
} | |
var scroller = (function () { | |
var | |
mobile = !!( | |
navigator.userAgent.match(/Android/i) || | |
navigator.userAgent.match(/webOS/i) || | |
navigator.userAgent.match(/iPhone/i) || | |
navigator.userAgent.match(/iPod/i) | |
), | |
mozilla = !!$.browser.mozilla; | |
return (!mobile || mozilla); | |
})(); | |
Flotr.Examples = Examples; | |
})(); | |
(function () { | |
var | |
D = Flotr.DOM, | |
E = Flotr.EventAdapter, | |
_ = Flotr._, | |
CLICK = 'click', | |
ID_EXAMPLE_PROFILE = 'example-profile', | |
ID_EXAMPLES = 'examples', | |
Profile = function (o) { | |
if (_.isUndefined(Flotr.ExampleList)) throw "Flotr.ExampleList not defined."; | |
this.editMode = 'off'; | |
this.list = Flotr.ExampleList; | |
this.current = null; | |
this.single = false; | |
this.init(); | |
}; | |
Profile.prototype = _.extend({}, Flotr.Examples.prototype, { | |
examples : function () { | |
var | |
examplesNode = document.getElementById(ID_EXAMPLES), | |
listNode = D.node('<ul></ul>'), | |
profileNode; | |
_.each(this.list.getType('profile'), function (example) { | |
profileNode = D.node('<li>' + example.name + '</li>'); | |
D.insert(listNode, profileNode); | |
E.observe(profileNode, CLICK, _.bind(function () { | |
this.example(example); | |
}, this)); | |
}, this); | |
D.insert(examplesNode, listNode); | |
}, | |
example : function (example) { | |
this._renderSource(example); | |
this.profileStart(example); | |
setTimeout(_.bind(function () { | |
this._renderGraph(example); | |
this.profileEnd(); | |
}, this), 50); | |
}, | |
profileStart : function (example) { | |
var profileNode = document.getElementById(ID_EXAMPLE_PROFILE); | |
this._startTime = new Date(); | |
profileNode.innerHTML = '<div>Profile started for "'+example.name+'"...</div>'; | |
}, | |
profileEnd : function (example) { | |
var | |
profileNode = document.getElementById(ID_EXAMPLE_PROFILE); | |
profileTime = (new Date()) - this._startTime; | |
this._startTime = null; | |
profileNode.innerHTML += '<div>Profile complete: '+profileTime+'ms<div>'; | |
} | |
}); | |
Flotr.Profile = Profile; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'advanced-markers', | |
name : 'Advanced Markers', | |
callback : advanced_markers, | |
timeout : 150 | |
}); | |
function advanced_markers (container) { | |
var | |
xmark = new Image(), | |
checkmark = new Image(), | |
bars = { | |
data: [], | |
bars: { | |
show: true, | |
barWidth: 0.6, | |
lineWidth: 0, | |
fillOpacity: 0.8 | |
} | |
}, markers = { | |
data: [], | |
markers: { | |
show: true, | |
position: 'ct', | |
labelFormatter: function (o) { | |
return (o.y >= 5) ? checkmark : xmark; | |
} | |
} | |
}, | |
flotr = Flotr, | |
point, | |
graph, | |
i; | |
for (i = 0; i < 8; i++) { | |
point = [i, Math.ceil(Math.random() * 10)]; | |
bars.data.push(point); | |
markers.data.push(point); | |
} | |
var runner = function () { | |
if (!xmark.complete || !checkmark.complete) { | |
setTimeout(runner, 50); | |
return; | |
} | |
graph = flotr.draw( | |
container, | |
[bars, markers], { | |
yaxis: { | |
min: 0, | |
max: 11 | |
}, | |
xaxis: { | |
min: -0.5, | |
max: 7.5 | |
}, | |
grid: { | |
verticalLines: false | |
} | |
} | |
); | |
} | |
xmark.onload = runner; | |
xmark.src = 'images/xmark.png'; | |
checkmark.src = 'images/checkmark.png'; | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'advanced-titles', | |
name : 'Advanced Titles', | |
callback : advanced_titles | |
}); | |
function advanced_titles (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
d4 = [], | |
d5 = [], | |
graph, | |
i; | |
for (i = 0; i <= 10; i += 0.1) { | |
d1.push([i, 4 + Math.pow(i,1.5)]); | |
d2.push([i, Math.pow(i,3)]); | |
d3.push([i, i*5+3*Math.sin(i*4)]); | |
d4.push([i, i]); | |
if (i.toFixed(1)%1 == 0) { | |
d5.push([i, 2*i]); | |
} | |
} | |
// Draw the graph. | |
graph = Flotr.draw( | |
container,[ | |
{ data : d1, label : 'y = 4 + x^(1.5)', lines : { fill : true } }, | |
{ data : d2, label : 'y = x^3', yaxis : 2 }, | |
{ data : d3, label : 'y = 5x + 3sin(4x)' }, | |
{ data : d4, label : 'y = x' }, | |
{ data : d5, label : 'y = 2x', lines : { show : true }, points : { show : true } } | |
], { | |
title : 'Advanced Titles Example', | |
subtitle : 'You can save me as an image', | |
xaxis : { | |
noTicks : 7, | |
tickFormatter : function (n) { return '('+n+')'; }, | |
min : 1, | |
max : 7.5, | |
labelsAngle : 45, | |
title : 'x Axis' | |
}, | |
yaxis : { | |
ticks : [[0, "Lower"], 10, 20, 30, [40, "Upper"]], | |
max : 40, | |
title : 'y = f(x)' | |
}, | |
y2axis : { color : '#FF0000', max : 500, title : 'y = x^3' }, | |
grid : { | |
verticalLines : false, | |
backgroundColor : 'white' | |
}, | |
HtmlText : false, | |
legend : { | |
position : 'nw' | |
} | |
}); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-axis', | |
name : 'Basic Axis', | |
callback : basic_axis | |
}); | |
function basic_axis (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
d4 = [], | |
d5 = [], // Data | |
ticks = [[ 0, "Lower"], 10, 20, 30, [40, "Upper"]], // Ticks for the Y-Axis | |
graph; | |
for(var i = 0; i <= 10; i += 0.1){ | |
d1.push([i, 4 + Math.pow(i,1.5)]); | |
d2.push([i, Math.pow(i,3)]); | |
d3.push([i, i*5+3*Math.sin(i*4)]); | |
d4.push([i, i]); | |
if( i.toFixed(1)%1 == 0 ){ | |
d5.push([i, 2*i]); | |
} | |
} | |
d3[30][1] = null; | |
d3[31][1] = null; | |
function ticksFn (n) { return '('+n+')'; } | |
graph = Flotr.draw(container, [ | |
{ data : d1, label : 'y = 4 + x^(1.5)', lines : { fill : true } }, | |
{ data : d2, label : 'y = x^3'}, | |
{ data : d3, label : 'y = 5x + 3sin(4x)'}, | |
{ data : d4, label : 'y = x'}, | |
{ data : d5, label : 'y = 2x', lines : { show : true }, points : { show : true } } | |
], { | |
xaxis : { | |
noTicks : 7, // Display 7 ticks. | |
tickFormatter : ticksFn, // Displays tick values between brackets. | |
min : 1, // Part of the series is not displayed. | |
max : 7.5 // Part of the series is not displayed. | |
}, | |
yaxis : { | |
ticks : ticks, // Set Y-Axis ticks | |
max : 40 // Maximum value along Y-Axis | |
}, | |
grid : { | |
verticalLines : false, | |
backgroundColor : { | |
colors : [[0,'#fff'], [1,'#ccc']], | |
start : 'top', | |
end : 'bottom' | |
} | |
}, | |
legend : { | |
position : 'nw' | |
}, | |
title : 'Basic Axis example', | |
subtitle : 'This is a subtitle' | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-bar-stacked', | |
name : 'Stacked Bars', | |
callback : bars_stacked | |
}); | |
Flotr.ExampleList.add({ | |
key : 'basic-stacked-horizontal', | |
name : 'Stacked Horizontal Bars', | |
args : [true], | |
callback : bars_stacked, | |
tolerance : 5 | |
}); | |
function bars_stacked (container, horizontal) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
graph, i; | |
for (i = -10; i < 10; i++) { | |
if (horizontal) { | |
d1.push([Math.random(), i]); | |
d2.push([Math.random(), i]); | |
d3.push([Math.random(), i]); | |
} else { | |
d1.push([i, Math.random()]); | |
d2.push([i, Math.random()]); | |
d3.push([i, Math.random()]); | |
} | |
} | |
graph = Flotr.draw(container,[ | |
{ data : d1, label : 'Serie 1' }, | |
{ data : d2, label : 'Serie 2' }, | |
{ data : d3, label : 'Serie 3' } | |
], { | |
legend : { | |
backgroundColor : '#D2E8FF' // Light blue | |
}, | |
bars : { | |
show : true, | |
stacked : true, | |
horizontal : horizontal, | |
barWidth : 0.6, | |
lineWidth : 1, | |
shadowSize : 0 | |
}, | |
grid : { | |
verticalLines : horizontal, | |
horizontalLines : !horizontal | |
} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-bars', | |
name : 'Basic Bars', | |
callback : basic_bars | |
}); | |
Flotr.ExampleList.add({ | |
key : 'basic-bars-horizontal', | |
name : 'Horizontal Bars', | |
args : [true], | |
callback : basic_bars, | |
tolerance : 5 | |
}); | |
function basic_bars (container, horizontal) { | |
var | |
horizontal = (horizontal ? true : false), // Show horizontal bars | |
d1 = [], // First data series | |
d2 = [], // Second data series | |
point, // Data point variable declaration | |
i; | |
for (i = 0; i < 4; i++) { | |
if (horizontal) { | |
point = [Math.ceil(Math.random()*10), i]; | |
} else { | |
point = [i, Math.ceil(Math.random()*10)]; | |
} | |
d1.push(point); | |
if (horizontal) { | |
point = [Math.ceil(Math.random()*10), i+0.5]; | |
} else { | |
point = [i+0.5, Math.ceil(Math.random()*10)]; | |
} | |
d2.push(point); | |
}; | |
// Draw the graph | |
Flotr.draw( | |
container, | |
[d1, d2], | |
{ | |
bars : { | |
show : true, | |
horizontal : horizontal, | |
shadowSize : 0, | |
barWidth : 0.5 | |
}, | |
mouse : { | |
track : true, | |
relative : true | |
}, | |
yaxis : { | |
min : 0, | |
autoscaleMargin : 1 | |
} | |
} | |
); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-bubble', | |
name : 'Basic Bubble', | |
callback : basic_bubble | |
}); | |
function basic_bubble (container) { | |
var | |
d1 = [], | |
d2 = [], | |
point, graph, i; | |
for (i = 0; i < 10; i++ ){ | |
point = [i, Math.ceil(Math.random()*10), Math.ceil(Math.random()*10)]; | |
d1.push(point); | |
point = [i, Math.ceil(Math.random()*10), Math.ceil(Math.random()*10)]; | |
d2.push(point); | |
} | |
// Draw the graph | |
graph = Flotr.draw(container, [d1, d2], { | |
bubbles : { show : true, baseRadius : 5 }, | |
xaxis : { min : -4, max : 14 }, | |
yaxis : { min : -4, max : 14 } | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-candle', | |
name : 'Basic Candle', | |
callback : basic_candle | |
}); | |
function basic_candle (container) { | |
var | |
d1 = [], | |
price = 3.206, | |
graph, | |
i, a, b, c; | |
for (i = 0; i < 50; i++) { | |
a = Math.random(); | |
b = Math.random(); | |
c = (Math.random() * (a + b)) - b; | |
d1.push([i, price, price + a, price - b, price + c]); | |
price = price + c; | |
} | |
// Graph | |
graph = Flotr.draw(container, [ d1 ], { | |
candles : { show : true, candleWidth : 0.6 }, | |
xaxis : { noTicks : 10 } | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-legend', | |
name : 'Basic Legend', | |
callback : basic_legend | |
}); | |
function basic_legend (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
data, | |
graph, i; | |
// Data Generation | |
for (i = 0; i < 15; i += 0.5) { | |
d1.push([i, i + Math.sin(i+Math.PI)]); | |
d2.push([i, i]); | |
d3.push([i, 15-Math.cos(i)]); | |
} | |
data = [ | |
{ data : d1, label :'x + sin(x+π)' }, | |
{ data : d2, label :'x' }, | |
{ data : d3, label :'15 - cos(x)' } | |
]; | |
// This function prepend each label with 'y = ' | |
function labelFn (label) { | |
return 'y = ' + label; | |
} | |
// Draw graph | |
graph = Flotr.draw(container, data, { | |
legend : { | |
position : 'se', // Position the legend 'south-east'. | |
labelFormatter : labelFn, // Format the labels. | |
backgroundColor : '#D2E8FF' // A light blue background color. | |
}, | |
HtmlText : false | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-pie', | |
name : 'Basic Pie', | |
callback : basic_pie | |
}); | |
function basic_pie (container) { | |
var | |
d1 = [[0, 4]], | |
d2 = [[0, 3]], | |
d3 = [[0, 1.03]], | |
d4 = [[0, 3.5]], | |
graph; | |
graph = Flotr.draw(container, [ | |
{ data : d1, label : 'Comedy' }, | |
{ data : d2, label : 'Action' }, | |
{ data : d3, label : 'Romance', | |
pie : { | |
explode : 50 | |
} | |
}, | |
{ data : d4, label : 'Drama' } | |
], { | |
HtmlText : false, | |
grid : { | |
verticalLines : false, | |
horizontalLines : false | |
}, | |
xaxis : { showLabels : false }, | |
yaxis : { showLabels : false }, | |
pie : { | |
show : true, | |
explode : 6 | |
}, | |
mouse : { track : true }, | |
legend : { | |
position : 'se', | |
backgroundColor : '#D2E8FF' | |
} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-radar', | |
name : 'Basic Radar', | |
callback : basic_radar | |
}); | |
function basic_radar (container) { | |
// Fill series s1 and s2. | |
var | |
s1 = { label : 'Actual', data : [[0, 3], [1, 8], [2, 5], [3, 5], [4, 3], [5, 9]] }, | |
s2 = { label : 'Target', data : [[0, 8], [1, 7], [2, 8], [3, 2], [4, 4], [5, 7]] }, | |
graph, ticks; | |
// Radar Labels | |
ticks = [ | |
[0, "Statutory"], | |
[1, "External"], | |
[2, "Videos"], | |
[3, "Yippy"], | |
[4, "Management"], | |
[5, "oops"] | |
]; | |
// Draw the graph. | |
graph = Flotr.draw(container, [ s1, s2 ], { | |
radar : { show : true}, | |
grid : { circular : true, minorHorizontalLines : true}, | |
yaxis : { min : 0, max : 10, minorTickFreq : 2}, | |
xaxis : { ticks : ticks} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-stacked', | |
name : 'Basic Stacked', | |
callback : basic_stacked, | |
type : 'test' | |
}); | |
function basic_stacked (container) { | |
var | |
d1 = [[0, 3], [4, 8], [8, 2], [9, 3]], // First data series | |
d2 = [[0, 2], [4, 3], [8, 8], [9, 4]], // Second data series | |
i, graph; | |
// Draw Graph | |
graph = Flotr.draw(container, [ d1, d2 ], { | |
lines: { | |
show : true, | |
stacked: true | |
}, | |
xaxis: { | |
minorTickFreq: 4 | |
}, | |
grid: { | |
minorVerticalLines: true | |
} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-stepped', | |
name : 'Basic Stepped', | |
callback : basic_stepped, | |
type : 'test' | |
}); | |
function basic_stepped (container) { | |
var | |
d1 = [[0, 3], [4, 8], [8, 5], [9, 13]], // First data series | |
d2 = [], // Second data series | |
i, graph; | |
// Generate first data set | |
for (i = 0; i < 14; i += 0.5) { | |
d2.push([i, Math.sin(i)]); | |
} | |
// Draw Graph | |
graph = Flotr.draw(container, [ d1, d2 ], { | |
lines: { | |
steps : true, | |
show : true | |
}, | |
xaxis: { | |
minorTickFreq: 4 | |
}, | |
yaxis: { | |
autoscale: true | |
}, | |
grid: { | |
minorVerticalLines: true | |
}, | |
mouse : { | |
track : true, | |
relative : true | |
} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-time', | |
name : 'Basic Time', | |
callback : basic_time, | |
description : "<p>Select an area of the graph to zoom. Click to reset the chart.</p>" | |
}); | |
function basic_time (container) { | |
var | |
d1 = [], | |
start = new Date("2009/01/01 01:00").getTime(), | |
options, | |
graph, | |
i, x, o; | |
for (i = 0; i < 100; i++) { | |
x = start+(i*1000*3600*24*36.5); | |
d1.push([x, i+Math.random()*30+Math.sin(i/20+Math.random()*2)*20+Math.sin(i/10+Math.random())*10]); | |
} | |
options = { | |
xaxis : { | |
mode : 'time', | |
labelsAngle : 45 | |
}, | |
selection : { | |
mode : 'x' | |
}, | |
HtmlText : false, | |
title : 'Time' | |
}; | |
// Draw graph with default options, overwriting with passed options | |
function drawGraph (opts) { | |
// Clone the options, so the 'options' variable always keeps intact. | |
o = Flotr._.extend(Flotr._.clone(options), opts || {}); | |
// Return a new graph. | |
return Flotr.draw( | |
container, | |
[ d1 ], | |
o | |
); | |
} | |
graph = drawGraph(); | |
Flotr.EventAdapter.observe(container, 'flotr:select', function(area){ | |
// Draw selected area | |
graph = drawGraph({ | |
xaxis : { min : area.x1, max : area.x2, mode : 'time', labelsAngle : 45 }, | |
yaxis : { min : area.y1, max : area.y2 } | |
}); | |
}); | |
// When graph is clicked, draw the graph with default area. | |
Flotr.EventAdapter.observe(container, 'flotr:click', function () { graph = drawGraph(); }); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic-timeline', | |
name : 'Basic Timeline', | |
callback : basic_timeline | |
}); | |
function basic_timeline (container) { | |
var | |
d1 = [[1, 4, 5]], | |
d2 = [[3.2, 3, 4]], | |
d3 = [[1.9, 2, 2], [5, 2, 3.3]], | |
d4 = [[1.55, 1, 9]], | |
d5 = [[5, 0, 2.3]], | |
data = [], | |
timeline = { show : true, barWidth : .5 }, | |
markers = [], | |
labels = ['Obama', 'Bush', 'Clinton', 'Palin', 'McCain'], | |
i, graph, point; | |
// Timeline | |
Flotr._.each([d1, d2, d3, d4, d5], function (d) { | |
data.push({ | |
data : d, | |
timeline : Flotr._.clone(timeline) | |
}); | |
}); | |
// Markers | |
Flotr._.each([d1, d2, d3, d4, d5], function (d) { | |
point = d[0]; | |
markers.push([point[0], point[1]]); | |
}); | |
data.push({ | |
data: markers, | |
markers: { | |
show: true, | |
position: 'rm', | |
fontSize: 11, | |
labelFormatter : function (o) { return labels[o.index]; } | |
} | |
}); | |
// Draw Graph | |
graph = Flotr.draw(container, data, { | |
xaxis: { | |
noTicks: 3, | |
tickFormatter: function (x) { | |
var | |
x = parseInt(x), | |
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; | |
return months[(x-1)%12]; | |
} | |
}, | |
yaxis: { | |
showLabels : false | |
}, | |
grid: { | |
horizontalLines : false | |
} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'basic', | |
name : 'Basic', | |
callback : basic | |
}); | |
function basic (container) { | |
var | |
d1 = [[0, 3], [4, 8], [8, 5], [9, 13]], // First data series | |
d2 = [], // Second data series | |
i, graph; | |
// Generate first data set | |
for (i = 0; i < 14; i += 0.5) { | |
d2.push([i, Math.sin(i)]); | |
} | |
// Draw Graph | |
graph = Flotr.draw(container, [ d1, d2 ], { | |
xaxis: { | |
minorTickFreq: 4 | |
}, | |
grid: { | |
minorVerticalLines: true | |
} | |
}); | |
} | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'click-example', | |
name : 'Click Example', | |
callback : click_example | |
}); | |
function click_example (container) { | |
var | |
d1 = [[0,0]], // Point at origin | |
options, | |
graph; | |
options = { | |
xaxis: {min: 0, max: 15}, | |
yaxis: {min: 0, max: 15}, | |
lines: {show: true}, | |
points: {show: true}, | |
mouse: {track:true}, | |
title: 'Click Example' | |
}; | |
graph = Flotr.draw(container, [d1], options); | |
// Add a point to the series and redraw the graph | |
Flotr.EventAdapter.observe(container, 'flotr:click', function(position){ | |
// Add a point to the series at the location of the click | |
d1.push([position.x, position.y]); | |
// Sort the series. | |
d1 = d1.sort(function (a, b) { return a[0] - b[0]; }); | |
// Redraw the graph, with the new series. | |
graph = Flotr.draw(container, [d1], options); | |
}); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'color-gradients', | |
name : 'Color Gradients', | |
callback : color_gradients | |
}); | |
function color_gradients (container) { | |
var | |
bars = { | |
data: [], | |
bars: { | |
show: true, | |
barWidth: 0.8, | |
lineWidth: 0, | |
fillColor: { | |
colors: ['#CB4B4B', '#fff'], | |
start: 'top', | |
end: 'bottom' | |
}, | |
fillOpacity: 0.8 | |
} | |
}, markers = { | |
data: [], | |
markers: { | |
show: true, | |
position: 'ct' | |
} | |
}, lines = { | |
data: [], | |
lines: { | |
show: true, | |
fillColor: ['#00A8F0', '#fff'], | |
fill: true, | |
fillOpacity: 1 | |
} | |
}, | |
point, | |
graph, | |
i; | |
for (i = 0; i < 8; i++) { | |
point = [i, Math.ceil(Math.random() * 10)]; | |
bars.data.push(point); | |
markers.data.push(point); | |
} | |
for (i = -1; i < 9; i += 0.01){ | |
lines.data.push([i, i*i/8+2]); | |
} | |
graph = Flotr.draw( | |
container, | |
[lines, bars, markers], { | |
yaxis: { | |
min: 0, | |
max: 11 | |
}, | |
xaxis: { | |
min: -0.5, | |
max: 7.5 | |
}, | |
grid: { | |
verticalLines: false, | |
backgroundColor: ['#fff', '#ccc'] | |
} | |
} | |
); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'download-data', | |
name : 'Download Data', | |
callback : download_data | |
}); | |
function download_data (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
d4 = [], | |
d5 = [], | |
graph, | |
i,x; | |
for (i = 0; i <= 100; i += 1) { | |
x = i / 10; | |
d1.push([x, 4 + Math.pow(x,1.5)]); | |
d2.push([x, Math.pow(x,3)]); | |
d3.push([x, i*5+3*Math.sin(x*4)]); | |
d4.push([x, x]); | |
if(x%1 === 0 ){ | |
d5.push([x, 2*x]); | |
} | |
} | |
// Draw the graph. | |
graph = Flotr.draw( | |
container, [ | |
{ data : d1, label : 'y = 4 + x^(1.5)', lines : { fill : true } }, | |
{ data : d2, label : 'y = x^3' }, | |
{ data : d3, label : 'y = 5x + 3sin(4x)' }, | |
{ data : d4, label : 'y = x' }, | |
{ data : d5, label : 'y = 2x', lines : { show : true }, points : { show : true } } | |
],{ | |
xaxis : { | |
noTicks : 7, | |
tickFormatter : function (n) { return '('+n+')'; }, | |
min: 1, // Part of the series is not displayed. | |
max: 7.5 | |
}, | |
yaxis : { | |
ticks : [[ 0, "Lower"], 10, 20, 30, [40, "Upper"]], | |
max : 40 | |
}, | |
grid : { | |
verticalLines : false, | |
backgroundColor : 'white' | |
}, | |
legend : { | |
position : 'nw' | |
}, | |
spreadsheet : { | |
show : true, | |
tickFormatter : function (e) { return e+''; } | |
} | |
}); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'download-image', | |
name : 'Download Image', | |
callback : download_image, | |
description : '' + | |
'<form name="image-download" id="image-download" action="" onsubmit="return false">' + | |
'<label><input type="radio" name="format" value="png" checked="checked" /> PNG</label>' + | |
'<label><input type="radio" name="format" value="jpeg" /> JPEG</label>' + | |
'<button name="to-image" onclick="CurrentExample(\'to-image\')">To Image</button>' + | |
'<button name="download" onclick="CurrentExample(\'download\')">Download</button>' + | |
'<button name="reset" onclick="CurrentExample(\'reset\')">Reset</button>' + | |
'</form>' | |
}); | |
function download_image (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
d4 = [], | |
d5 = [], | |
graph, | |
i; | |
for (i = 0; i <= 10; i += 0.1) { | |
d1.push([i, 4 + Math.pow(i,1.5)]); | |
d2.push([i, Math.pow(i,3)]); | |
d3.push([i, i*5+3*Math.sin(i*4)]); | |
d4.push([i, i]); | |
if( i.toFixed(1)%1 == 0 ){ | |
d5.push([i, 2*i]); | |
} | |
} | |
// Draw the graph | |
graph = Flotr.draw( | |
container,[ | |
{data:d1, label:'y = 4 + x^(1.5)', lines:{fill:true}}, | |
{data:d2, label:'y = x^3', yaxis:2}, | |
{data:d3, label:'y = 5x + 3sin(4x)'}, | |
{data:d4, label:'y = x'}, | |
{data:d5, label:'y = 2x', lines: {show: true}, points: {show: true}} | |
],{ | |
title: 'Download Image Example', | |
subtitle: 'You can save me as an image', | |
xaxis:{ | |
noTicks: 7, // Display 7 ticks. | |
tickFormatter: function(n){ return '('+n+')'; }, // => displays tick values between brackets. | |
min: 1, // => part of the series is not displayed. | |
max: 7.5, // => part of the series is not displayed. | |
labelsAngle: 45, | |
title: 'x Axis' | |
}, | |
yaxis:{ | |
ticks: [[0, "Lower"], 10, 20, 30, [40, "Upper"]], | |
max: 40, | |
title: 'y = f(x)' | |
}, | |
y2axis:{color:'#FF0000', max: 500, title: 'y = x^3'}, | |
grid:{ | |
verticalLines: false, | |
backgroundColor: 'white' | |
}, | |
HtmlText: false, | |
legend: { | |
position: 'nw' | |
} | |
}); | |
this.CurrentExample = function (operation) { | |
var | |
format = $('#image-download input:radio[name=format]:checked').val(); | |
if (Flotr.isIE && Flotr.isIE < 9) { | |
alert( | |
"Your browser doesn't allow you to get a bitmap image from the plot, " + | |
"you can only get a VML image that you can use in Microsoft Office.<br />" | |
); | |
} | |
if (operation == 'to-image') { | |
graph.download.saveImage(format, null, null, true) | |
} else if (operation == 'download') { | |
graph.download.saveImage(format); | |
} else if (operation == 'reset') { | |
graph.download.restoreCanvas(); | |
} | |
}; | |
return graph; | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'mouse-drag', | |
name : 'Mouse Drag', | |
callback : mouse_drag | |
}); | |
function mouse_drag (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
options, | |
graph, | |
start, | |
i; | |
for (i = -40; i < 40; i += 0.5) { | |
d1.push([i, Math.sin(i)+3*Math.cos(i)]); | |
d2.push([i, Math.pow(1.1, i)]); | |
d3.push([i, 40 - i+Math.random()*10]); | |
} | |
options = { | |
xaxis: {min: 0, max: 20}, | |
title : 'Mouse Drag' | |
}; | |
// Draw graph with default options, overwriting with passed options | |
function drawGraph (opts) { | |
// Clone the options, so the 'options' variable always keeps intact. | |
var o = Flotr._.extend(Flotr._.clone(options), opts || {}); | |
// Return a new graph. | |
return Flotr.draw( | |
container, | |
[ d1, d2, d3 ], | |
o | |
); | |
} | |
graph = drawGraph(); | |
function initializeDrag (e) { | |
start = graph.getEventPosition(e); | |
Flotr.EventAdapter.observe(document, 'mousemove', move); | |
Flotr.EventAdapter.observe(document, 'mouseup', stopDrag); | |
} | |
function move (e) { | |
var | |
end = graph.getEventPosition(e), | |
xaxis = graph.axes.x, | |
offset = start.x - end.x; | |
graph = drawGraph({ | |
xaxis : { | |
min : xaxis.min + offset, | |
max : xaxis.max + offset | |
} | |
}); | |
// @todo: refector initEvents in order not to remove other observed events | |
Flotr.EventAdapter.observe(graph.overlay, 'mousedown', initializeDrag); | |
} | |
function stopDrag () { | |
Flotr.EventAdapter.stopObserving(document, 'mousemove', move); | |
} | |
Flotr.EventAdapter.observe(graph.overlay, 'mousedown', initializeDrag); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'mouse-tracking', | |
name : 'Mouse Tracking', | |
callback : mouse_tracking | |
}); | |
function mouse_tracking (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
graph, i; | |
for (i = 0; i < 20; i += 0.5) { | |
d1.push([i, 2*i]); | |
d2.push([i, i*1.5+1.5*Math.sin(i)]); | |
d3.push([i, 3*Math.cos(i)+10]); | |
} | |
graph = Flotr.draw( | |
container, | |
[ | |
{ | |
data : d1, | |
mouse : { track : false } // Disable mouse tracking for d1 | |
}, | |
d2, | |
d3 | |
], | |
{ | |
mouse : { | |
track : true, // Enable mouse tracking | |
lineColor : 'purple', | |
relative : true, | |
position : 'ne', | |
sensibility : 1, | |
trackDecimals : 2, | |
trackFormatter : function (o) { return 'x = ' + o.x +', y = ' + o.y; } | |
}, | |
crosshair : { | |
mode : 'xy' | |
} | |
} | |
); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'mouse-zoom', | |
name : 'Mouse Zoom', | |
callback : mouse_zoom, | |
description : "<p>Select an area of the graph to zoom. Click to reset the chart.</p>" | |
}); | |
function mouse_zoom (container) { | |
var | |
d1 = [], | |
d2 = [], | |
d3 = [], | |
options, | |
graph, | |
i; | |
for (i = 0; i < 40; i += 0.5) { | |
d1.push([i, Math.sin(i)+3*Math.cos(i)]); | |
d2.push([i, Math.pow(1.1, i)]); | |
d3.push([i, 40 - i+Math.random()*10]); | |
} | |
options = { | |
selection : { mode : 'x', fps : 30 }, | |
title : 'Mouse Zoom' | |
}; | |
// Draw graph with default options, overwriting with passed options | |
function drawGraph (opts) { | |
// Clone the options, so the 'options' variable always keeps intact. | |
var o = Flotr._.extend(Flotr._.clone(options), opts || {}); | |
// Return a new graph. | |
return Flotr.draw( | |
container, | |
[ d1, d2, d3 ], | |
o | |
); | |
} | |
// Actually draw the graph. | |
graph = drawGraph(); | |
// Hook into the 'flotr:select' event. | |
Flotr.EventAdapter.observe(container, 'flotr:select', function (area) { | |
// Draw graph with new area | |
graph = drawGraph({ | |
xaxis: {min:area.x1, max:area.x2}, | |
yaxis: {min:area.y1, max:area.y2} | |
}); | |
}); | |
// When graph is clicked, draw the graph with default area. | |
Flotr.EventAdapter.observe(container, 'flotr:click', function () { drawGraph(); }); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'negative-values', | |
name : 'Negative Values', | |
callback : negative_values | |
}); | |
function negative_values (container) { | |
var | |
d0 = [], // Line through y = 0 | |
d1 = [], // Random data presented as a scatter plot. | |
d2 = [], // A regression line for the scatter. | |
sx = 0, | |
sy = 0, | |
sxy = 0, | |
sxsq = 0, | |
xmean, | |
ymean, | |
alpha, | |
beta, | |
n, x, y; | |
for (n = 0; n < 20; n++){ | |
x = n; | |
y = x + Math.random()*8 - 15; | |
d0.push([x, 0]); | |
d1.push([x, y]); | |
// Computations used for regression line | |
sx += x; | |
sy += y; | |
sxy += x*y; | |
sxsq += Math.pow(x,2); | |
} | |
xmean = sx/n; | |
ymean = sy/n; | |
beta = ((n*sxy) - (sx*sy))/((n*sxsq)-(Math.pow(sx,2))); | |
alpha = ymean - (beta * xmean); | |
// Compute the regression line. | |
for (n = 0; n < 20; n++){ | |
d2.push([n, alpha + beta*n]) | |
} | |
// Draw the graph | |
graph = Flotr.draw( | |
container, [ | |
{ data : d0, shadowSize : 0, color : '#545454' }, // Horizontal | |
{ data : d1, label : 'y = x + (Math.random() * 8) - 15', points : { show : true } }, // Scatter | |
{ data : d2, label : 'y = ' + alpha.toFixed(2) + ' + ' + beta.toFixed(2) + '*x' } // Regression | |
], | |
{ | |
legend : { position : 'se', backgroundColor : '#D2E8FF' }, | |
title : 'Negative Values' | |
} | |
); | |
}; | |
})(); | |
(function () { | |
Flotr.ExampleList.add({ | |
key : 'profile-bars', | |
name : 'Profile Bars', | |
type : 'profile', | |
callback : profile_bars | |
}); | |
/* | |
Flotr.ExampleList.add({ | |
key : 'basic-bars-horizontal', | |
name : 'Horizontal Bars', | |
args : [true], | |
callback : basic_bars | |
}); | |
*/ | |
function profile_bars (container, horizontal) { | |
var | |
horizontal = (horizontal ? true : false), // Show horizontal bars | |
d1 = [], // First data series | |
d2 = [], // Second data series | |
point, // Data point variable declaration | |
i; | |
for (i = 0; i < 5000; i++) { | |
if (horizontal) { | |
point = [Math.ceil(Math.random()*10), i]; | |
} else { | |
point = [i, Math.ceil(Math.random()*10)]; | |
} | |
d1.push(point); | |
if (horizontal) { | |
point = [Math.ceil(Math.random()*10), i+0.5]; | |
} else { | |
point = [i+0.5, Math.ceil(Math.random()*10)]; | |
} | |
d2.push(point); | |
}; | |
// Draw the graph | |
Flotr.draw( | |
container, | |
[d1, d2], | |
{ | |
bars : { | |
show : true, | |
horizontal : horizontal, | |
barWidth : 0.5 | |
}, | |
mouse : { | |
track : true, | |
relative : true | |
}, | |
yaxis : { | |
min : 0, | |
autoscaleMargin : 1 | |
} | |
} | |
); | |
} | |
})(); | |
yepnope([ | |
// Libs | |
'../lib/bean-min.js', | |
'../lib/underscore-min.js', | |
{ | |
test : (navigator.appVersion.indexOf("MSIE") != -1 && parseFloat(navigator.appVersion.split("MSIE")[1]) < 9), | |
// Load for IE < 9 | |
yep : [ | |
'../lib/excanvas.js', | |
'../lib/base64.js', | |
'../lib/canvastext.js' | |
] | |
}, | |
'lib/codemirror/lib/codemirror.js', | |
'lib/codemirror/mode/javascript/javascript.js', | |
'lib/beautify.js', | |
'lib/randomseed.js', | |
'lib/jquery-1.7.1.min.js', | |
'lib/jquery.ba-hashchange.min.js', | |
// Flotr | |
'../js/Flotr.js', | |
'../js/DefaultOptions.js', | |
'../js/Color.js', | |
'../js/Date.js', | |
'../js/DOM.js', | |
'../js/EventAdapter.js', | |
'../js/Text.js', | |
'../js/Graph.js', | |
'../js/Axis.js', | |
'../js/Series.js', | |
'../js/types/lines.js', | |
'../js/types/bars.js', | |
'../js/types/points.js', | |
'../js/types/pie.js', | |
'../js/types/candles.js', | |
'../js/types/markers.js', | |
'../js/types/radar.js', | |
'../js/types/bubbles.js', | |
'../js/types/gantt.js', | |
'../js/types/timeline.js', | |
'../js/plugins/download.js', | |
'../js/plugins/selection.js', | |
'../js/plugins/spreadsheet.js', | |
'../js/plugins/grid.js', | |
'../js/plugins/hit.js', | |
'../js/plugins/crosshair.js', | |
'../js/plugins/labels.js', | |
'../js/plugins/legend.js', | |
'../js/plugins/titles.js', | |
// Examples | |
'js/Examples.js', | |
'js/ExampleList.js', | |
'js/Example.js', | |
'js/Editor.js', | |
'js/Profile.js', | |
'js/examples/basic.js', | |
'js/examples/basic-axis.js', | |
'js/examples/basic-bars.js', | |
'js/examples/basic-bars-stacked.js', | |
'js/examples/basic-pie.js', | |
'js/examples/basic-radar.js', | |
'js/examples/basic-bubble.js', | |
'js/examples/basic-candle.js', | |
'js/examples/basic-legend.js', | |
'js/examples/mouse-tracking.js', | |
'js/examples/mouse-zoom.js', | |
'js/examples/mouse-drag.js', | |
'js/examples/basic-time.js', | |
'js/examples/negative-values.js', | |
'js/examples/click-example.js', | |
'js/examples/download-image.js', | |
'js/examples/download-data.js', | |
'js/examples/advanced-titles.js', | |
'js/examples/color-gradients.js', | |
'js/examples/profile-bars.js', | |
'js/examples/basic-timeline.js', | |
'js/examples/advanced-markers.js', | |
{ complete : function () { | |
if (Flotr.ExamplesCallback) { | |
Flotr.ExamplesCallback(); | |
} else { | |
Examples = new Flotr.Examples({ | |
node : document.getElementById('examples') | |
}); | |
} | |
} | |
} | |
]); | |
yepnope([ | |
{ | |
test : (navigator.appVersion.indexOf("MSIE") != -1 && parseFloat(navigator.appVersion.split("MSIE")[1]) < 9), | |
// Load for IE < 9 | |
yep : [ | |
'../flotr2.ie.min.js' | |
] | |
}, | |
'../flotr2.min.js', | |
'lib/codemirror/lib/codemirror.js', | |
'lib/codemirror/mode/javascript/javascript.js', | |
'lib/beautify.js', | |
'lib/randomseed.js', | |
'lib/jquery-1.7.1.min.js', | |
'lib/jquery.ba-hashchange.min.js', | |
// Examples | |
'../flotr2.examples.min.js', | |
'../flotr2.examples.types.js', | |
{ complete : function () { | |
if (Flotr.ExamplesCallback) { | |
Flotr.ExamplesCallback(); | |
} else { | |
Examples = new Flotr.Examples({ | |
node : document.getElementById('examples') | |
}); | |
} | |
} | |
} | |
]); | |
/*jslint onevar: false, plusplus: false */ | |
/* | |
JS Beautifier | |
--------------- | |
Written by Einar Lielmanis, <einar@jsbeautifier.org> | |
http://jsbeautifier.org/ | |
Originally converted to javascript by Vital, <vital76@gmail.com> | |
"End braces on own line" added by Chris J. Shull, <chrisjshull@gmail.com> | |
You are free to use this in any way you want, in case you find this useful or working for you. | |
Usage: | |
js_beautify(js_source_text); | |
js_beautify(js_source_text, options); | |
The options are: | |
indent_size (default 4) — indentation size, | |
indent_char (default space) — character to indent with, | |
preserve_newlines (default true) — whether existing line breaks should be preserved, | |
preserve_max_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk, | |
jslint_happy (default false) — if true, then jslint-stricter mode is enforced. | |
jslint_happy !jslint_happy | |
--------------------------------- | |
function () function() | |
brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | |
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line. | |
e.g | |
js_beautify(js_source_text, { | |
'indent_size': 1, | |
'indent_char': '\t' | |
}); | |
*/ | |
function js_beautify(js_source_text, options) { | |
var input, output, token_text, last_type, last_text, last_last_text, last_word, flags, flag_store, indent_string; | |
var whitespace, wordchar, punct, parser_pos, line_starters, digits; | |
var prefix, token_type, do_block_just_closed; | |
var wanted_newline, just_added_newline, n_newlines; | |
var preindent_string = ''; | |
// Some interpreters have unexpected results with foo = baz || bar; | |
options = options ? options : {}; | |
var opt_brace_style; | |
// compatibility | |
if (options.space_after_anon_function !== undefined && options.jslint_happy === undefined) { | |
options.jslint_happy = options.space_after_anon_function; | |
} | |
if (options.braces_on_own_line !== undefined) { //graceful handling of depricated option | |
opt_brace_style = options.braces_on_own_line ? "expand" : "collapse"; | |
} | |
opt_brace_style = options.brace_style ? options.brace_style : (opt_brace_style ? opt_brace_style : "collapse"); | |
var opt_indent_size = options.indent_size ? options.indent_size : 4; | |
var opt_indent_char = options.indent_char ? options.indent_char : ' '; | |
var opt_preserve_newlines = typeof options.preserve_newlines === 'undefined' ? true : options.preserve_newlines; | |
var opt_max_preserve_newlines = typeof options.max_preserve_newlines === 'undefined' ? false : options.max_preserve_newlines; | |
var opt_jslint_happy = options.jslint_happy === 'undefined' ? false : options.jslint_happy; | |
var opt_keep_array_indentation = typeof options.keep_array_indentation === 'undefined' ? false : options.keep_array_indentation; | |
just_added_newline = false; | |
// cache the source's length. | |
var input_length = js_source_text.length; | |
function trim_output(eat_newlines) { | |
eat_newlines = typeof eat_newlines === 'undefined' ? false : eat_newlines; | |
while (output.length && (output[output.length - 1] === ' ' | |
|| output[output.length - 1] === indent_string | |
|| output[output.length - 1] === preindent_string | |
|| (eat_newlines && (output[output.length - 1] === '\n' || output[output.length - 1] === '\r')))) { | |
output.pop(); | |
} | |
} | |
function trim(s) { | |
return s.replace(/^\s\s*|\s\s*$/, ''); | |
} | |
function force_newline() | |
{ | |
var old_keep_array_indentation = opt_keep_array_indentation; | |
opt_keep_array_indentation = false; | |
print_newline() | |
opt_keep_array_indentation = old_keep_array_indentation; | |
} | |
function print_newline(ignore_repeated) { | |
flags.eat_next_space = false; | |
if (opt_keep_array_indentation && is_array(flags.mode)) { | |
return; | |
} | |
ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated; | |
flags.if_line = false; | |
trim_output(); | |
if (!output.length) { | |
return; // no newline on start of file | |
} | |
if (output[output.length - 1] !== "\n" || !ignore_repeated) { | |
just_added_newline = true; | |
output.push("\n"); | |
} | |
if (preindent_string) { | |
output.push(preindent_string); | |
} | |
for (var i = 0; i < flags.indentation_level; i += 1) { | |
output.push(indent_string); | |
} | |
if (flags.var_line && flags.var_line_reindented) { | |
output.push(indent_string); // skip space-stuffing, if indenting with a tab | |
} | |
} | |
function print_single_space() { | |
if (flags.eat_next_space) { | |
flags.eat_next_space = false; | |
return; | |
} | |
var last_output = ' '; | |
if (output.length) { | |
last_output = output[output.length - 1]; | |
} | |
if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string) { // prevent occassional duplicate space | |
output.push(' '); | |
} | |
} | |
function print_token() { | |
just_added_newline = false; | |
flags.eat_next_space = false; | |
output.push(token_text); | |
} | |
function indent() { | |
flags.indentation_level += 1; | |
} | |
function remove_indent() { | |
if (output.length && output[output.length - 1] === indent_string) { | |
output.pop(); | |
} | |
} | |
function set_mode(mode) { | |
if (flags) { | |
flag_store.push(flags); | |
} | |
flags = { | |
previous_mode: flags ? flags.mode : 'BLOCK', | |
mode: mode, | |
var_line: false, | |
var_line_tainted: false, | |
var_line_reindented: false, | |
in_html_comment: false, | |
if_line: false, | |
in_case: false, | |
eat_next_space: false, | |
indentation_baseline: -1, | |
indentation_level: (flags ? flags.indentation_level + ((flags.var_line && flags.var_line_reindented) ? 1 : 0) : 0), | |
ternary_depth: 0 | |
}; | |
} | |
function is_array(mode) { | |
return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]'; | |
} | |
function is_expression(mode) { | |
return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]' || mode === '(EXPRESSION)'; | |
} | |
function restore_mode() { | |
do_block_just_closed = flags.mode === 'DO_BLOCK'; | |
if (flag_store.length > 0) { | |
flags = flag_store.pop(); | |
} | |
} | |
function all_lines_start_with(lines, c) { | |
for (var i = 0; i < lines.length; i++) { | |
if (trim(lines[i])[0] != c) { | |
return false; | |
} | |
} | |
return true; | |
} | |
function in_array(what, arr) { | |
for (var i = 0; i < arr.length; i += 1) { | |
if (arr[i] === what) { | |
return true; | |
} | |
} | |
return false; | |
} | |
function get_next_token() { | |
n_newlines = 0; | |
if (parser_pos >= input_length) { | |
return ['', 'TK_EOF']; | |
} | |
wanted_newline = false; | |
var c = input.charAt(parser_pos); | |
parser_pos += 1; | |
var keep_whitespace = opt_keep_array_indentation && is_array(flags.mode); | |
if (keep_whitespace) { | |
// | |
// slight mess to allow nice preservation of array indentation and reindent that correctly | |
// first time when we get to the arrays: | |
// var a = [ | |
// ....'something' | |
// we make note of whitespace_count = 4 into flags.indentation_baseline | |
// so we know that 4 whitespaces in original source match indent_level of reindented source | |
// | |
// and afterwards, when we get to | |
// 'something, | |
// .......'something else' | |
// we know that this should be indented to indent_level + (7 - indentation_baseline) spaces | |
// | |
var whitespace_count = 0; | |
while (in_array(c, whitespace)) { | |
if (c === "\n") { | |
trim_output(); | |
output.push("\n"); | |
just_added_newline = true; | |
whitespace_count = 0; | |
} else { | |
if (c === '\t') { | |
whitespace_count += 4; | |
} else if (c === '\r') { | |
// nothing | |
} else { | |
whitespace_count += 1; | |
} | |
} | |
if (parser_pos >= input_length) { | |
return ['', 'TK_EOF']; | |
} | |
c = input.charAt(parser_pos); | |
parser_pos += 1; | |
} | |
if (flags.indentation_baseline === -1) { | |
flags.indentation_baseline = whitespace_count; | |
} | |
if (just_added_newline) { | |
var i; | |
for (i = 0; i < flags.indentation_level + 1; i += 1) { | |
output.push(indent_string); | |
} | |
if (flags.indentation_baseline !== -1) { | |
for (i = 0; i < whitespace_count - flags.indentation_baseline; i++) { | |
output.push(' '); | |
} | |
} | |
} | |
} else { | |
while (in_array(c, whitespace)) { | |
if (c === "\n") { | |
n_newlines += ( (opt_max_preserve_newlines) ? (n_newlines <= opt_max_preserve_newlines) ? 1: 0: 1 ); | |
} | |
if (parser_pos >= input_length) { | |
return ['', 'TK_EOF']; | |
} | |
c = input.charAt(parser_pos); | |
parser_pos += 1; | |
} | |
if (opt_preserve_newlines) { | |
if (n_newlines > 1) { | |
for (i = 0; i < n_newlines; i += 1) { | |
print_newline(i === 0); | |
just_added_newline = true; | |
} | |
} | |
} | |
wanted_newline = n_newlines > 0; | |
} | |
if (in_array(c, wordchar)) { | |
if (parser_pos < input_length) { | |
while (in_array(input.charAt(parser_pos), wordchar)) { | |
c += input.charAt(parser_pos); | |
parser_pos += 1; | |
if (parser_pos === input_length) { | |
break; | |
} | |
} | |
} | |
// small and surprisingly unugly hack for 1E-10 representation | |
if (parser_pos !== input_length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+')) { | |
var sign = input.charAt(parser_pos); | |
parser_pos += 1; | |
var t = get_next_token(parser_pos); | |
c += sign + t[0]; | |
return [c, 'TK_WORD']; | |
} | |
if (c === 'in') { // hack for 'in' operator | |
return [c, 'TK_OPERATOR']; | |
} | |
if (wanted_newline && last_type !== 'TK_OPERATOR' | |
&& last_type !== 'TK_EQUALS' | |
&& !flags.if_line && (opt_preserve_newlines || last_text !== 'var')) { | |
print_newline(); | |
} | |
return [c, 'TK_WORD']; | |
} | |
if (c === '(' || c === '[') { | |
return [c, 'TK_START_EXPR']; | |
} | |
if (c === ')' || c === ']') { | |
return [c, 'TK_END_EXPR']; | |
} | |
if (c === '{') { | |
return [c, 'TK_START_BLOCK']; | |
} | |
if (c === '}') { | |
return [c, 'TK_END_BLOCK']; | |
} | |
if (c === ';') { | |
return [c, 'TK_SEMICOLON']; | |
} | |
if (c === '/') { | |
var comment = ''; | |
// peek for comment /* ... */ | |
var inline_comment = true; | |
if (input.charAt(parser_pos) === '*') { | |
parser_pos += 1; | |
if (parser_pos < input_length) { | |
while (! (input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') && parser_pos < input_length) { | |
c = input.charAt(parser_pos); | |
comment += c; | |
if (c === '\x0d' || c === '\x0a') { | |
inline_comment = false; | |
} | |
parser_pos += 1; | |
if (parser_pos >= input_length) { | |
break; | |
} | |
} | |
} | |
parser_pos += 2; | |
if (inline_comment) { | |
return ['/*' + comment + '*/', 'TK_INLINE_COMMENT']; | |
} else { | |
return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT']; | |
} | |
} | |
// peek for comment // ... | |
if (input.charAt(parser_pos) === '/') { | |
comment = c; | |
while (input.charAt(parser_pos) !== '\r' && input.charAt(parser_pos) !== '\n') { | |
comment += input.charAt(parser_pos); | |
parser_pos += 1; | |
if (parser_pos >= input_length) { | |
break; | |
} | |
} | |
parser_pos += 1; | |
if (wanted_newline) { | |
print_newline(); | |
} | |
return [comment, 'TK_COMMENT']; | |
} | |
} | |
if (c === "'" || // string | |
c === '"' || // string | |
(c === '/' && | |
((last_type === 'TK_WORD' && in_array(last_text, ['return', 'do'])) || | |
(last_type === 'TK_COMMENT' || last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EQUALS' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON')))) { // regexp | |
var sep = c; | |
var esc = false; | |
var resulting_string = c; | |
if (parser_pos < input_length) { | |
if (sep === '/') { | |
// | |
// handle regexp separately... | |
// | |
var in_char_class = false; | |
while (esc || in_char_class || input.charAt(parser_pos) !== sep) { | |
resulting_string += input.charAt(parser_pos); | |
if (!esc) { | |
esc = input.charAt(parser_pos) === '\\'; | |
if (input.charAt(parser_pos) === '[') { | |
in_char_class = true; | |
} else if (input.charAt(parser_pos) === ']') { | |
in_char_class = false; | |
} | |
} else { | |
esc = false; | |
} | |
parser_pos += 1; | |
if (parser_pos >= input_length) { | |
// incomplete string/rexp when end-of-file reached. | |
// bail out with what had been received so far. | |
return [resulting_string, 'TK_STRING']; | |
} | |
} | |
} else { | |
// | |
// and handle string also separately | |
// | |
while (esc || input.charAt(parser_pos) !== sep) { | |
resulting_string += input.charAt(parser_pos); | |
if (!esc) { | |
esc = input.charAt(parser_pos) === '\\'; | |
} else { | |
esc = false; | |
} | |
parser_pos += 1; | |
if (parser_pos >= input_length) { | |
// incomplete string/rexp when end-of-file reached. | |
// bail out with what had been received so far. | |
return [resulting_string, 'TK_STRING']; | |
} | |
} | |
} | |
} | |
parser_pos += 1; | |
resulting_string += sep; | |
if (sep === '/') { | |
// regexps may have modifiers /regexp/MOD , so fetch those, too | |
while (parser_pos < input_length && in_array(input.charAt(parser_pos), wordchar)) { | |
resulting_string += input.charAt(parser_pos); | |
parser_pos += 1; | |
} | |
} | |
return [resulting_string, 'TK_STRING']; | |
} | |
if (c === '#') { | |
if (output.length === 0 && input.charAt(parser_pos) === '!') { | |
// shebang | |
resulting_string = c; | |
while (parser_pos < input_length && c != '\n') { | |
c = input.charAt(parser_pos); | |
resulting_string += c; | |
parser_pos += 1; | |
} | |
output.push(trim(resulting_string) + '\n'); | |
print_newline(); | |
return get_next_token(); | |
} | |
// Spidermonkey-specific sharp variables for circular references | |
// https://developer.mozilla.org/En/Sharp_variables_in_JavaScript | |
// http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935 | |
var sharp = '#'; | |
if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits)) { | |
do { | |
c = input.charAt(parser_pos); | |
sharp += c; | |
parser_pos += 1; | |
} while (parser_pos < input_length && c !== '#' && c !== '='); | |
if (c === '#') { | |
// | |
} else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']') { | |
sharp += '[]'; | |
parser_pos += 2; | |
} else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}') { | |
sharp += '{}'; | |
parser_pos += 2; | |
} | |
return [sharp, 'TK_WORD']; | |
} | |
} | |
if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--') { | |
parser_pos += 3; | |
flags.in_html_comment = true; | |
return ['<!--', 'TK_COMMENT']; | |
} | |
if (c === '-' && flags.in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->') { | |
flags.in_html_comment = false; | |
parser_pos += 2; | |
if (wanted_newline) { | |
print_newline(); | |
} | |
return ['-->', 'TK_COMMENT']; | |
} | |
if (in_array(c, punct)) { | |
while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct)) { | |
c += input.charAt(parser_pos); | |
parser_pos += 1; | |
if (parser_pos >= input_length) { | |
break; | |
} | |
} | |
if (c === '=') { | |
return [c, 'TK_EQUALS']; | |
} else { | |
return [c, 'TK_OPERATOR']; | |
} | |
} | |
return [c, 'TK_UNKNOWN']; | |
} | |
//---------------------------------- | |
indent_string = ''; | |
while (opt_indent_size > 0) { | |
indent_string += opt_indent_char; | |
opt_indent_size -= 1; | |
} | |
while (js_source_text && (js_source_text[0] === ' ' || js_source_text[0] === '\t')) { | |
preindent_string += js_source_text[0]; | |
js_source_text = js_source_text.substring(1); | |
} | |
input = js_source_text; | |
last_word = ''; // last 'TK_WORD' passed | |
last_type = 'TK_START_EXPR'; // last token type | |
last_text = ''; // last token text | |
last_last_text = ''; // pre-last token text | |
output = []; | |
do_block_just_closed = false; | |
whitespace = "\n\r\t ".split(''); | |
wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split(''); | |
digits = '0123456789'.split(''); | |
punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::'.split(' '); | |
// words which should always start on new line. | |
line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(','); | |
// states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'. | |
// some formatting depends on that. | |
flag_store = []; | |
set_mode('BLOCK'); | |
parser_pos = 0; | |
while (true) { | |
var t = get_next_token(parser_pos); | |
token_text = t[0]; | |
token_type = t[1]; | |
if (token_type === 'TK_EOF') { | |
break; | |
} | |
switch (token_type) { | |
case 'TK_START_EXPR': | |
if (token_text === '[') { | |
if (last_type === 'TK_WORD' || last_text === ')') { | |
// this is array index specifier, break immediately | |
// a[x], fn()[x] | |
if (in_array(last_text, line_starters)) { | |
print_single_space(); | |
} | |
set_mode('(EXPRESSION)'); | |
print_token(); | |
break; | |
} | |
if (flags.mode === '[EXPRESSION]' || flags.mode === '[INDENTED-EXPRESSION]') { | |
if (last_last_text === ']' && last_text === ',') { | |
// ], [ goes to new line | |
if (flags.mode === '[EXPRESSION]') { | |
flags.mode = '[INDENTED-EXPRESSION]'; | |
if (!opt_keep_array_indentation) { | |
indent(); | |
} | |
} | |
set_mode('[EXPRESSION]'); | |
if (!opt_keep_array_indentation) { | |
print_newline(); | |
} | |
} else if (last_text === '[') { | |
if (flags.mode === '[EXPRESSION]') { | |
flags.mode = '[INDENTED-EXPRESSION]'; | |
if (!opt_keep_array_indentation) { | |
indent(); | |
} | |
} | |
set_mode('[EXPRESSION]'); | |
if (!opt_keep_array_indentation) { | |
print_newline(); | |
} | |
} else { | |
set_mode('[EXPRESSION]'); | |
} | |
} else { | |
set_mode('[EXPRESSION]'); | |
} | |
} else { | |
set_mode('(EXPRESSION)'); | |
} | |
if (last_text === ';' || last_type === 'TK_START_BLOCK') { | |
print_newline(); | |
} else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || last_text === '.') { | |
// do nothing on (( and )( and ][ and ]( and .( | |
} else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') { | |
print_single_space(); | |
} else if (last_word === 'function' || last_word === 'typeof') { | |
// function() vs function () | |
if (opt_jslint_happy) { | |
print_single_space(); | |
} | |
} else if (in_array(last_text, line_starters) || last_text === 'catch') { | |
print_single_space(); | |
} | |
print_token(); | |
break; | |
case 'TK_END_EXPR': | |
if (token_text === ']') { | |
if (opt_keep_array_indentation) { | |
if (last_text === '}') { | |
// trim_output(); | |
// print_newline(true); | |
remove_indent(); | |
print_token(); | |
restore_mode(); | |
break; | |
} | |
} else { | |
if (flags.mode === '[INDENTED-EXPRESSION]') { | |
if (last_text === ']') { | |
restore_mode(); | |
print_newline(); | |
print_token(); | |
break; | |
} | |
} | |
} | |
} | |
restore_mode(); | |
print_token(); | |
break; | |
case 'TK_START_BLOCK': | |
if (last_word === 'do') { | |
set_mode('DO_BLOCK'); | |
} else { | |
set_mode('BLOCK'); | |
} | |
if (opt_brace_style=="expand") { | |
if (last_type !== 'TK_OPERATOR') { | |
if (last_text === 'return' || last_text === '=') { | |
print_single_space(); | |
} else { | |
print_newline(true); | |
} | |
} | |
print_token(); | |
indent(); | |
} else { | |
if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') { | |
if (last_type === 'TK_START_BLOCK') { | |
print_newline(); | |
} else { | |
print_single_space(); | |
} | |
} else { | |
// if TK_OPERATOR or TK_START_EXPR | |
if (is_array(flags.previous_mode) && last_text === ',') { | |
if (last_last_text === '}') { | |
// }, { in array context | |
print_single_space(); | |
} else { | |
print_newline(); // [a, b, c, { | |
} | |
} | |
} | |
indent(); | |
print_token(); | |
} | |
break; | |
case 'TK_END_BLOCK': | |
restore_mode(); | |
if (opt_brace_style=="expand") { | |
if (last_text !== '{') { | |
print_newline(); | |
} | |
print_token(); | |
} else { | |
if (last_type === 'TK_START_BLOCK') { | |
// nothing | |
if (just_added_newline) { | |
remove_indent(); | |
} else { | |
// {} | |
trim_output(); | |
} | |
} else { | |
if (is_array(flags.mode) && opt_keep_array_indentation) { | |
// we REALLY need a newline here, but newliner would skip that | |
opt_keep_array_indentation = false; | |
print_newline(); | |
opt_keep_array_indentation = true; | |
} else { | |
print_newline(); | |
} | |
} | |
print_token(); | |
} | |
break; | |
case 'TK_WORD': | |
// no, it's not you. even I have problems understanding how this works | |
// and what does what. | |
if (do_block_just_closed) { | |
// do {} ## while () | |
print_single_space(); | |
print_token(); | |
print_single_space(); | |
do_block_just_closed = false; | |
break; | |
} | |
if (token_text === 'function') { | |
if (flags.var_line) { | |
flags.var_line_reindented = true; | |
} | |
if ((just_added_newline || last_text === ';') && last_text !== '{') { | |
// make sure there is a nice clean space of at least one blank line | |
// before a new function definition | |
n_newlines = just_added_newline ? n_newlines : 0; | |
if ( ! opt_preserve_newlines) { | |
n_newlines = 1; | |
} | |
for (var i = 0; i < 2 - n_newlines; i++) { | |
print_newline(false); | |
} | |
} | |
} | |
if (token_text === 'case' || token_text === 'default') { | |
if (last_text === ':') { | |
// switch cases following one another | |
remove_indent(); | |
} else { | |
// case statement starts in the same line where switch | |
flags.indentation_level--; | |
print_newline(); | |
flags.indentation_level++; | |
} | |
print_token(); | |
flags.in_case = true; | |
break; | |
} | |
prefix = 'NONE'; | |
if (last_type === 'TK_END_BLOCK') { | |
if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) { | |
prefix = 'NEWLINE'; | |
} else { | |
if (opt_brace_style=="expand" || opt_brace_style=="end-expand") { | |
prefix = 'NEWLINE'; | |
} else { | |
prefix = 'SPACE'; | |
print_single_space(); | |
} | |
} | |
} else if (last_type === 'TK_SEMICOLON' && (flags.mode === 'BLOCK' || flags.mode === 'DO_BLOCK')) { | |
prefix = 'NEWLINE'; | |
} else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode)) { | |
prefix = 'SPACE'; | |
} else if (last_type === 'TK_STRING') { | |
prefix = 'NEWLINE'; | |
} else if (last_type === 'TK_WORD') { | |
if (last_text === 'else') { | |
// eat newlines between ...else *** some_op... | |
// won't preserve extra newlines in this place (if any), but don't care that much | |
trim_output(true); | |
} | |
prefix = 'SPACE'; | |
} else if (last_type === 'TK_START_BLOCK') { | |
prefix = 'NEWLINE'; | |
} else if (last_type === 'TK_END_EXPR') { | |
print_single_space(); | |
prefix = 'NEWLINE'; | |
} | |
if (in_array(token_text, line_starters) && last_text !== ')') { | |
if (last_text == 'else') { | |
prefix = 'SPACE'; | |
} else { | |
prefix = 'NEWLINE'; | |
} | |
} | |
if (flags.if_line && last_type === 'TK_END_EXPR') { | |
flags.if_line = false; | |
} | |
if (in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) { | |
if (last_type !== 'TK_END_BLOCK' || opt_brace_style=="expand" || opt_brace_style=="end-expand") { | |
print_newline(); | |
} else { | |
trim_output(true); | |
print_single_space(); | |
} | |
} else if (prefix === 'NEWLINE') { | |
if ((last_type === 'TK_START_EXPR' || last_text === '=' || last_text === ',') && token_text === 'function') { | |
// no need to force newline on 'function': (function | |
// DONOTHING | |
} else if (token_text === 'function' && last_text == 'new') { | |
print_single_space(); | |
} else if (last_text === 'return' || last_text === 'throw') { | |
// no newline between 'return nnn' | |
print_single_space(); | |
} else if (last_type !== 'TK_END_EXPR') { | |
if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':') { | |
// no need to force newline on 'var': for (var x = 0...) | |
if (token_text === 'if' && last_word === 'else' && last_text !== '{') { | |
// no newline for } else if { | |
print_single_space(); | |
} else { | |
flags.var_line = false; | |
flags.var_line_reindented = false; | |
print_newline(); | |
} | |
} | |
} else if (in_array(token_text, line_starters) && last_text != ')') { | |
flags.var_line = false; | |
flags.var_line_reindented = false; | |
print_newline(); | |
} | |
} else if (is_array(flags.mode) && last_text === ',' && last_last_text === '}') { | |
print_newline(); // }, in lists get a newline treatment | |
} else if (prefix === 'SPACE') { | |
print_single_space(); | |
} | |
print_token(); | |
last_word = token_text; | |
if (token_text === 'var') { | |
flags.var_line = true; | |
flags.var_line_reindented = false; | |
flags.var_line_tainted = false; | |
} | |
if (token_text === 'if') { | |
flags.if_line = true; | |
} | |
if (token_text === 'else') { | |
flags.if_line = false; | |
} | |
break; | |
case 'TK_SEMICOLON': | |
print_token(); | |
flags.var_line = false; | |
flags.var_line_reindented = false; | |
if (flags.mode == 'OBJECT') { | |
// OBJECT mode is weird and doesn't get reset too well. | |
flags.mode = 'BLOCK'; | |
} | |
break; | |
case 'TK_STRING': | |
if (last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_SEMICOLON') { | |
print_newline(); | |
} else if (last_type === 'TK_WORD') { | |
print_single_space(); | |
} | |
print_token(); | |
break; | |
case 'TK_EQUALS': | |
if (flags.var_line) { | |
// just got an '=' in a var-line, different formatting/line-breaking, etc will now be done | |
flags.var_line_tainted = true; | |
} | |
print_single_space(); | |
print_token(); | |
print_single_space(); | |
break; | |
case 'TK_OPERATOR': | |
var space_before = true; | |
var space_after = true; | |
if (flags.var_line && token_text === ',' && (is_expression(flags.mode))) { | |
// do not break on comma, for(var a = 1, b = 2) | |
flags.var_line_tainted = false; | |
} | |
if (flags.var_line) { | |
if (token_text === ',') { | |
if (flags.var_line_tainted) { | |
print_token(); | |
flags.var_line_reindented = true; | |
flags.var_line_tainted = false; | |
print_newline(); | |
break; | |
} else { | |
flags.var_line_tainted = false; | |
} | |
// } else if (token_text === ':') { | |
// hmm, when does this happen? tests don't catch this | |
// flags.var_line = false; | |
} | |
} | |
if (last_text === 'return' || last_text === 'throw') { | |
// "return" had a special handling in TK_WORD. Now we need to return the favor | |
print_single_space(); | |
print_token(); | |
break; | |
} | |
if (token_text === ':' && flags.in_case) { | |
print_token(); // colon really asks for separate treatment | |
print_newline(); | |
flags.in_case = false; | |
break; | |
} | |
if (token_text === '::') { | |
// no spaces around exotic namespacing syntax operator | |
print_token(); | |
break; | |
} | |
if (token_text === ',') { | |
if (flags.var_line) { | |
if (flags.var_line_tainted) { | |
print_token(); | |
print_newline(); | |
flags.var_line_tainted = false; | |
} else { | |
print_token(); | |
print_single_space(); | |
} | |
} else if (last_type === 'TK_END_BLOCK' && flags.mode !== "(EXPRESSION)") { | |
print_token(); | |
if (flags.mode === 'OBJECT' && last_text === '}') { | |
print_newline(); | |
} else { | |
print_single_space(); | |
} | |
} else { | |
if (flags.mode === 'OBJECT') { | |
print_token(); | |
print_newline(); | |
} else { | |
// EXPR or DO_BLOCK | |
print_token(); | |
print_single_space(); | |
} | |
} | |
break; | |
// } else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS']) || in_array(last_text, line_starters) || in_array(last_text, ['==', '!=', '+=', '-=', '*=', '/=', '+', '-'])))) { | |
} else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) || in_array(last_text, line_starters)))) { | |
// unary operators (and binary +/- pretending to be unary) special cases | |
space_before = false; | |
space_after = false; | |
if (last_text === ';' && is_expression(flags.mode)) { | |
// for (;; ++i) | |
// ^^^ | |
space_before = true; | |
} | |
if (last_type === 'TK_WORD' && in_array(last_text, line_starters)) { | |
space_before = true; | |
} | |
if (flags.mode === 'BLOCK' && (last_text === '{' || last_text === ';')) { | |
// { foo; --i } | |
// foo(); --bar; | |
print_newline(); | |
} | |
} else if (token_text === '.') { | |
// decimal digits or object.property | |
space_before = false; | |
} else if (token_text === ':') { | |
if (flags.ternary_depth == 0) { | |
flags.mode = 'OBJECT'; | |
space_before = false; | |
} else { | |
flags.ternary_depth -= 1; | |
} | |
} else if (token_text === '?') { | |
flags.ternary_depth += 1; | |
} | |
if (space_before) { | |
print_single_space(); | |
} | |
print_token(); | |
if (space_after) { | |
print_single_space(); | |
} | |
if (token_text === '!') { | |
// flags.eat_next_space = true; | |
} | |
break; | |
case 'TK_BLOCK_COMMENT': | |
var lines = token_text.split(/\x0a|\x0d\x0a/); | |
if (all_lines_start_with(lines.slice(1), '*')) { | |
// javadoc: reformat and reindent | |
print_newline(); | |
output.push(lines[0]); | |
for (i = 1; i < lines.length; i++) { | |
print_newline(); | |
output.push(' '); | |
output.push(trim(lines[i])); | |
} | |
} else { | |
// simple block comment: leave intact | |
if (lines.length > 1) { | |
// multiline comment block starts with a new line | |
print_newline(); | |
trim_output(); | |
} else { | |
// single-line /* comment */ stays where it is | |
print_single_space(); | |
} | |
for (i = 0; i < lines.length; i++) { | |
output.push(lines[i]); | |
output.push('\n'); | |
} | |
} | |
print_newline(); | |
break; | |
case 'TK_INLINE_COMMENT': | |
print_single_space(); | |
print_token(); | |
if (is_expression(flags.mode)) { | |
print_single_space(); | |
} else { | |
force_newline(); | |
} | |
break; | |
case 'TK_COMMENT': | |
// print_newline(); | |
if (wanted_newline) { | |
print_newline(); | |
} else { | |
print_single_space(); | |
} | |
print_token(); | |
force_newline(); | |
break; | |
case 'TK_UNKNOWN': | |
if (last_text === 'return' || last_text === 'throw') { | |
print_single_space(); | |
} | |
print_token(); | |
break; | |
} | |
last_last_text = last_text; | |
last_type = token_type; | |
last_text = token_text; | |
} | |
var sweet_code = preindent_string + output.join('').replace(/[\n ]+$/, ''); | |
return sweet_code; | |
} | |
// Add support for CommonJS. Just put this file somewhere on your require.paths | |
// and you will be able to `var js_beautify = require("beautify").js_beautify`. | |
if (typeof exports !== "undefined") | |
exports.js_beautify = js_beautify; | |
Copyright (C) 2011 by Marijn Haverbeke <marijnh@gmail.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. | |
# CodeMirror 2 | |
CodeMirror 2 is a rewrite of [CodeMirror | |
1](http://github.com/marijnh/CodeMirror). The docs live | |
[here](http://codemirror.net/doc/manual.html), and the project page is | |
[http://codemirror.net/](http://codemirror.net/). | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Active Line Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../mode/xml/xml.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} | |
.activeline {background: #f0fcff !important;} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Active Line Demo</h1> | |
<form><textarea id="code" name="code"> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" | |
xmlns:georss="http://www.georss.org/georss" | |
xmlns:twitter="http://api.twitter.com"> | |
<channel> | |
<title>Twitter / codemirror</title> | |
<link>http://twitter.com/codemirror</link> | |
<atom:link type="application/rss+xml" | |
href="http://twitter.com/statuses/user_timeline/242283288.rss" rel="self"/> | |
<description>Twitter updates from CodeMirror / codemirror.</description> | |
<language>en-us</language> | |
<ttl>40</ttl> | |
<item> | |
<title>codemirror: http://cloud-ide.com — they're springing up like mushrooms. This one | |
uses CodeMirror as its editor.</title> | |
<description>codemirror: http://cloud-ide.com — they're springing up like mushrooms. This | |
one uses CodeMirror as its editor.</description> | |
<pubDate>Thu, 17 Mar 2011 23:34:47 +0000</pubDate> | |
<guid>http://twitter.com/codemirror/statuses/48527733722058752</guid> | |
<link>http://twitter.com/codemirror/statuses/48527733722058752</link> | |
<twitter:source>web</twitter:source> | |
<twitter:place/> | |
</item> | |
<item> | |
<title>codemirror: Posted a description of the CodeMirror 2 internals at | |
http://codemirror.net/2/internals.html</title> | |
<description>codemirror: Posted a description of the CodeMirror 2 internals at | |
http://codemirror.net/2/internals.html</description> | |
<pubDate>Wed, 02 Mar 2011 12:15:09 +0000</pubDate> | |
<guid>http://twitter.com/codemirror/statuses/42920879788789760</guid> | |
<link>http://twitter.com/codemirror/statuses/42920879788789760</link> | |
<twitter:source>web</twitter:source> | |
<twitter:place/> | |
</item> | |
</channel> | |
</rss></textarea></form> | |
<script> | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
mode: "application/xml", | |
lineNumbers: true, | |
onCursorActivity: function() { | |
editor.setLineClass(hlLine, null); | |
hlLine = editor.setLineClass(editor.getCursor().line, "activeline"); | |
} | |
}); | |
var hlLine = editor.setLineClass(0, "activeline"); | |
</script> | |
<p>Styling the current cursor line.</p> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Mode-Changing Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../mode/javascript/javascript.js"></script> | |
<script src="../mode/scheme/scheme.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror {border: 1px solid black;} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Mode-Changing demo</h1> | |
<form><textarea id="code" name="code"> | |
;; If there is Scheme code in here, the editor will be in Scheme mode. | |
;; If you put in JS instead, it'll switch to JS mode. | |
(define (double x) | |
(* x x)) | |
</textarea></form> | |
<p>On changes to the content of the above editor, a (crude) script | |
tries to auto-detect the language used, and switches the editor to | |
either JavaScript or Scheme mode based on that.</p> | |
<script> | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
mode: "scheme", | |
lineNumbers: true, | |
matchBrackets: true, | |
tabMode: "indent", | |
onChange: function() { | |
clearTimeout(pending); | |
setTimeout(update, 400); | |
} | |
}); | |
var pending; | |
function looksLikeScheme(code) { | |
return !/^\s*\(\s*function\b/.test(code) && /^\s*[;\(]/.test(code); | |
} | |
function update() { | |
editor.setOption("mode", looksLikeScheme(editor.getValue()) ? "scheme" : "javascript"); | |
} | |
</script> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Autocomplete Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../lib/util/simple-hint.js"></script> | |
<link rel="stylesheet" href="../lib/util/simple-hint.css"> | |
<script src="../lib/util/javascript-hint.js"></script> | |
<script src="../mode/javascript/javascript.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css">.CodeMirror {border: 1px solid #eee;}</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Autocomplete demo</h1> | |
<form><textarea id="code" name="code"> | |
function getCompletions(token, context) { | |
var found = [], start = token.string; | |
function maybeAdd(str) { | |
if (str.indexOf(start) == 0) found.push(str); | |
} | |
function gatherCompletions(obj) { | |
if (typeof obj == "string") forEach(stringProps, maybeAdd); | |
else if (obj instanceof Array) forEach(arrayProps, maybeAdd); | |
else if (obj instanceof Function) forEach(funcProps, maybeAdd); | |
for (var name in obj) maybeAdd(name); | |
} | |
if (context) { | |
// If this is a property, see if it belongs to some object we can | |
// find in the current environment. | |
var obj = context.pop(), base; | |
if (obj.className == "js-variable") | |
base = window[obj.string]; | |
else if (obj.className == "js-string") | |
base = ""; | |
else if (obj.className == "js-atom") | |
base = 1; | |
while (base != null && context.length) | |
base = base[context.pop().string]; | |
if (base != null) gatherCompletions(base); | |
} | |
else { | |
// If not, just look in the window object and any local scope | |
// (reading into JS mode internals to get at the local variables) | |
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); | |
gatherCompletions(window); | |
forEach(keywords, maybeAdd); | |
} | |
return found; | |
} | |
</textarea></form> | |
<p>Press <strong>ctrl-space</strong> to activate autocompletion. See | |
the code (<a href="../lib/util/simple-hint.js">here</a> | |
and <a href="../lib/util/javascript-hint.js">here</a>) to figure out | |
how it works.</p> | |
<script> | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true, | |
extraKeys: {"Ctrl-Space": function(cm) {CodeMirror.simpleHint(cm, CodeMirror.javascriptHint);}} | |
}); | |
</script> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Emacs bindings demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../mode/clike/clike.js"></script> | |
<script src="../keymap/emacs.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror {border-top: 1px solid #eee; border-bottom: 1px solid #eee;} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Emacs bindings demo</h1> | |
<form><textarea id="code" name="code"> | |
#include "syscalls.h" | |
/* getchar: simple buffered version */ | |
int getchar(void) | |
{ | |
static char buf[BUFSIZ]; | |
static char *bufp = buf; | |
static int n = 0; | |
if (n == 0) { /* buffer is empty */ | |
n = read(0, buf, sizeof buf); | |
bufp = buf; | |
} | |
return (--n >= 0) ? (unsigned char) *bufp++ : EOF; | |
} | |
</textarea></form> | |
<p>The emacs keybindings are enabled by | |
including <a href="../keymap/emacs.js">keymap/emacs.js</a> and setting | |
the <code>keyMap</code> option to <code>"emacs"</code>. Because | |
CodeMirror's internal API is quite different from Emacs, they are only | |
a loose approximation of actual emacs bindings, though.</p> | |
<p>Also note that a lot of browsers disallow certain keys from being | |
captured. For example, Chrome blocks both Ctrl-W and Ctrl-N, with the | |
result that idiomatic use of Emacs keys will constantly close your tab | |
or open a new window.</p> | |
<script> | |
CodeMirror.commands.save = function() { | |
var elt = editor.getWrapperElement(); | |
elt.style.background = "#def"; | |
setTimeout(function() { elt.style.background = ""; }, 300); | |
}; | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true, | |
mode: "text/x-csrc", | |
keyMap: "emacs" | |
}); | |
</script> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Code Folding Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../lib/util/foldcode.js"></script> | |
<script src="../mode/javascript/javascript.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} | |
.CodeMirror-gutter {min-width: 2.6em; cursor: pointer;} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Code Folding Demo</h1> | |
<form><div style="max-width: 50em"><textarea id="code" name="code"></textarea></div></form> | |
<script id="script"> | |
window.onload = function() { | |
var te = document.getElementById("code"); | |
var sc = document.getElementById("script"); | |
te.value = (sc.textContent || sc.innerText || sc.innerHTML).replace(/^\s*/, ""); | |
var foldFunc = CodeMirror.newFoldFunction(CodeMirror.braceRangeFinder); | |
function keyEvent(cm, e) { | |
if (e.keyCode == 81 && e.ctrlKey) { | |
if (e.type == "keydown") { | |
e.stop(); | |
setTimeout(function() {foldFunc(cm, cm.getCursor().line);}, 50); | |
} | |
return true; | |
} | |
} | |
window.editor = CodeMirror.fromTextArea(te, { | |
mode: "javascript", | |
lineNumbers: true, | |
lineWrapping: true, | |
onGutterClick: foldFunc, | |
extraKeys: {"Ctrl-Q": function(cm){foldFunc(cm, cm.getCursor().line);}} | |
}); | |
foldFunc(editor, 6); | |
foldFunc(editor, 16); | |
}; | |
</script> | |
<p>Demonstration of code folding using the code | |
in <a href="../lib/util/foldcode.js"><code>foldcode.js</code></a>. | |
Press ctrl-q or click on the gutter to fold a block, again | |
to unfold.</p> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Formatting Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../lib/util/formatting.js"></script> | |
<script src="../mode/css/css.js"></script> | |
<script src="../mode/xml/xml.js"></script> | |
<script src="../mode/javascript/javascript.js"></script> | |
<script src="../mode/htmlmixed/htmlmixed.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror { | |
border: 1px solid #eee; | |
} | |
td { | |
padding-right: 20px; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Formatting demo</h1> | |
<form><textarea id="code" name="code"><script> function (s,e){ for(var i=0; i < 1; i++) test("test();a=1");} </script> | |
<script> | |
function test(c){ for (var i = 0; i < 10; i++){ process("a.b();c = null;", 300);} | |
} | |
</script> | |
<table><tr><td>test 1</td></tr><tr><td>test 2</td></tr></table> | |
<script> function test() { return 1;} </script> | |
<style> .test { font-size: medium; font-family: monospace; } | |
</style></textarea></form> | |
<p>Select a piece of code and click one of the links below to apply automatic formatting to the selected text or comment/uncomment the selected text. Note that the formatting behavior depends on the current block's mode. | |
<table> | |
<tr> | |
<td> | |
<a href="javascript:autoFormatSelection()"> | |
Autoformat Selected | |
</a> | |
</td> | |
<td> | |
<a href="javascript:commentSelection(true)"> | |
Comment Selected | |
</a> | |
</td> | |
<td> | |
<a href="javascript:commentSelection(false)"> | |
Uncomment Selected | |
</a> | |
</td> | |
</tr> | |
</table> | |
</p> | |
<script> | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true, | |
mode: "htmlmixed" | |
}); | |
CodeMirror.commands["selectAll"](editor); | |
function getSelectedRange() { | |
return { from: editor.getCursor(true), to: editor.getCursor(false) }; | |
} | |
function autoFormatSelection() { | |
var range = getSelectedRange(); | |
editor.autoFormatRange(range.from, range.to); | |
} | |
function commentSelection(isComment) { | |
var range = getSelectedRange(); | |
editor.commentRange(isComment, range.from, range.to); | |
} | |
</script> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Full Screen Editing</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<link rel="stylesheet" href="../theme/night.css"> | |
<script src="../mode/xml/xml.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> | |
<style type="text/css"> | |
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} | |
.fullscreen { | |
display: block; | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: 9999; | |
margin: 0; | |
padding: 0; | |
border: 0px solid #BBBBBB; | |
opacity: 1; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Full Screen Editing</h1> | |
<form><textarea id="code" name="code" rows="5"> | |
<dt id="option_indentWithTabs"><code>indentWithTabs (boolean)</code></dt> | |
<dd>Whether, when indenting, the first N*8 spaces should be | |
replaced by N tabs. Default is false.</dd> | |
<dt id="option_tabMode"><code>tabMode (string)</code></dt> | |
<dd>Determines what happens when the user presses the tab key. | |
Must be one of the following: | |
<dl> | |
<dt><code>"classic" (the default)</code></dt> | |
<dd>When nothing is selected, insert a tab. Otherwise, | |
behave like the <code>"shift"</code> mode. (When shift is | |
held, this behaves like the <code>"indent"</code> mode.)</dd> | |
<dt><code>"shift"</code></dt> | |
<dd>Indent all selected lines by | |
one <a href="#option_indentUnit"><code>indentUnit</code></a>. | |
If shift was held while pressing tab, un-indent all selected | |
lines one unit.</dd> | |
<dt><code>"indent"</code></dt> | |
<dd>Indent the line the 'correctly', based on its syntactic | |
context. Only works if the | |
mode <a href="#indent">supports</a> it.</dd> | |
<dt><code>"default"</code></dt> | |
<dd>Do not capture tab presses, let the browser apply its | |
default behaviour (which usually means it skips to the next | |
control).</dd> | |
</dl></dd> | |
<dt id="option_enterMode"><code>enterMode (string)</code></dt> | |
<dd>Determines whether and how new lines are indented when the | |
enter key is pressed. The following modes are supported: | |
<dl> | |
<dt><code>"indent" (the default)</code></dt> | |
<dd>Use the mode's indentation rules to give the new line | |
the correct indentation.</dd> | |
<dt><code>"keep"</code></dt> | |
<dd>Indent the line the same as the previous line.</dd> | |
<dt><code>"flat"</code></dt> | |
<dd>Do not indent the new line.</dd> | |
</dl></dd> | |
<dt id="option_enterMode"><code>enterMode (string)</code></dt> | |
<dd>Determines whether and how new lines are indented when the | |
enter key is pressed. The following modes are supported: | |
<dl> | |
<dt><code>"indent" (the default)</code></dt> | |
<dd>Use the mode's indentation rules to give the new line | |
the correct indentation.</dd> | |
<dt><code>"keep"</code></dt> | |
<dd>Indent the line the same as the previous line.</dd> | |
<dt><code>"flat"</code></dt> | |
<dd>Do not indent the new line.</dd> | |
</dl></dd> | |
<dt id="option_enterMode"><code>enterMode (string)</code></dt> | |
<dd>Determines whether and how new lines are indented when the | |
enter key is pressed. The following modes are supported: | |
<dl> | |
<dt><code>"indent" (the default)</code></dt> | |
<dd>Use the mode's indentation rules to give the new line | |
the correct indentation.</dd> | |
<dt><code>"keep"</code></dt> | |
<dd>Indent the line the same as the previous line.</dd> | |
<dt><code>"flat"</code></dt> | |
<dd>Do not indent the new line.</dd> | |
</dl></dd> | |
<dt id="option_enterMode"><code>enterMode (string)</code></dt> | |
<dd>Determines whether and how new lines are indented when the | |
enter key is pressed. The following modes are supported: | |
<dl> | |
<dt><code>"indent" (the default)</code></dt> | |
<dd>Use the mode's indentation rules to give the new line | |
the correct indentation.</dd> | |
<dt><code>"keep"</code></dt> | |
<dd>Indent the line the same as the previous line.</dd> | |
<dt><code>"flat"</code></dt> | |
<dd>Do not indent the new line.</dd> | |
</dl></dd> | |
</textarea></form> | |
<script> | |
(function () { | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true, | |
theme: "night", | |
extraKeys: {"F11": toggleFullscreenEditing, "Esc": toggleFullscreenEditing} | |
}); | |
function toggleFullscreenEditing() | |
{ | |
var editorDiv = $('.CodeMirror-scroll'); | |
if (!editorDiv.hasClass('fullscreen')) { | |
toggleFullscreenEditing.beforeFullscreen = { height: editorDiv.height(), width: editorDiv.width() } | |
editorDiv.addClass('fullscreen'); | |
editorDiv.height('100%'); | |
editorDiv.width('100%'); | |
editor.refresh(); | |
} | |
else { | |
editorDiv.removeClass('fullscreen'); | |
editorDiv.height(toggleFullscreenEditing.beforeFullscreen.height); | |
editorDiv.width(toggleFullscreenEditing.beforeFullscreen.width); | |
editor.refresh(); | |
} | |
} | |
})(); | |
</script> | |
<p>Press <strong>F11</strong> (or <strong>ESC</strong> in Safari on Mac OS X) when cursor is in the editor to toggle full screen editing.</p> | |
<p><strong>Note:</strong> Does not currently work correctly in IE | |
6 and 7, where setting the height of something | |
to <code>100%</code> doesn't make it full-screen.</p> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Breakpoint Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../mode/javascript/javascript.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror-gutter { | |
width: 3em; | |
background: white; | |
} | |
.CodeMirror { | |
border: 1px solid #aaa; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Breakpoint demo</h1> | |
<form><textarea id="code" name="code"> | |
CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true, | |
onGutterClick: function(cm, n) { | |
var info = cm.lineInfo(n); | |
if (info.markerText) | |
cm.clearMarker(n); | |
else | |
cm.setMarker(n, "<span style=\"color: #900\">●</span> %N%"); | |
} | |
}); | |
</textarea></form> | |
<p>Click the line-number gutter to add or remove 'breakpoints'.</p> | |
<script> | |
CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true, | |
onGutterClick: function(cm, n) { | |
var info = cm.lineInfo(n); | |
if (info.markerText) | |
cm.clearMarker(n); | |
else | |
cm.setMarker(n, "<span style=\"color: #900\">●</span> %N%"); | |
} | |
}); | |
</script> | |
</body> | |
</html> | |
<!doctype html> | |
<html> | |
<head> | |
<title>CodeMirror: Overlay Parser Demo</title> | |
<link rel="stylesheet" href="../lib/codemirror.css"> | |
<script src="../lib/codemirror.js"></script> | |
<script src="../lib/util/overlay.js"></script> | |
<script src="../mode/xml/xml.js"></script> | |
<link rel="stylesheet" href="../doc/docs.css"> | |
<style type="text/css"> | |
.CodeMirror {border: 1px solid black;} | |
.cm-mustache {color: #0ca;} | |
</style> | |
</head> | |
<body> | |
<h1>CodeMirror: Overlay Parser Demo</h1> | |
<form><textarea id="code" name="code"> | |
<html> | |
<body> | |
<h1>{{title}}</h1> | |
<p>These are links to {{things}}:</p> | |
<ul>{{#links}} | |
<li><a href="{{url}}">{{text}}</a></li> | |
{{/links}}</ul> | |
</body> | |
</html> | |
</textarea></form> | |
<script> | |
CodeMirror.defineMode("mustache", function(config, parserConfig) { | |
var mustacheOverlay = { | |
token: function(stream, state) { | |
if (stream.match("{{")) { | |
while ((ch = stream.next()) != null) | |
if (ch == "}" && stream.next() == "}") break; | |
return "mustache"; | |
} |