From 39c8b14f56ebf8af47072fd9be136303e0032122 Mon Sep 17 00:00:00 2001 From: foldericon Date: Sun, 4 Nov 2012 09:00:14 +0100 Subject: [PATCH] initial commit --- JIRC.js | 178 + README | 62 + README.txt | 63 + lib/IRC.js | 458 +++ lib/entities.js | 291 ++ lib/entities.js.LICENSE | 20 + lib/googleweather.js | 120 + lib/listdb.js | 78 + lib/node-static.js | 260 ++ lib/node-static/mime.js | 140 + lib/node-static/util.js | 30 + node_modules/.DS_Store | Bin 0 -> 6148 bytes node_modules/growl/History.md | 58 + node_modules/growl/Readme.md | 99 + node_modules/growl/lib/growl.js | 232 ++ node_modules/growl/package.json | 13 + node_modules/growl/test.js | 20 + node_modules/jsdom/.npmignore | 6 + node_modules/jsdom/LICENSE.txt | 22 + node_modules/jsdom/README.md | 282 ++ node_modules/jsdom/benchmark/mark.js | 23 + node_modules/jsdom/benchmark/stats.json | 0 node_modules/jsdom/changelog | 169 + node_modules/jsdom/example/browser/browser.js | 34 + node_modules/jsdom/example/ender/ender.js | 1170 ++++++ node_modules/jsdom/example/ender/run.js | 10 + node_modules/jsdom/example/jquery/jquery.js | 167 + node_modules/jsdom/example/jquery/run.js | 9 + .../jsdom/example/node-xml/example.xml | 243 ++ node_modules/jsdom/example/node-xml/run.js | 45 + node_modules/jsdom/example/pure/pure.js | 742 ++++ node_modules/jsdom/example/pure/run.js | 96 + node_modules/jsdom/example/pure/sax-test.js | 11 + node_modules/jsdom/example/pure/sax.js | 535 +++ node_modules/jsdom/example/sizzle/run.js | 166 + node_modules/jsdom/example/sizzle/sax.js | 534 +++ node_modules/jsdom/example/sizzle/sizzle.js | 1066 +++++ node_modules/jsdom/lib/jsdom.js | 361 ++ .../lib/jsdom/browser/documentfeatures.js | 52 + .../jsdom/lib/jsdom/browser/domtohtml.js | 173 + .../jsdom/lib/jsdom/browser/htmlencoding.js | 1506 +++++++ .../jsdom/lib/jsdom/browser/htmltodom.js | 187 + node_modules/jsdom/lib/jsdom/browser/index.js | 613 +++ node_modules/jsdom/lib/jsdom/level1/core.js | 1764 +++++++++ node_modules/jsdom/lib/jsdom/level2/core.js | 643 +++ node_modules/jsdom/lib/jsdom/level2/events.js | 416 ++ node_modules/jsdom/lib/jsdom/level2/html.js | 1770 +++++++++ node_modules/jsdom/lib/jsdom/level2/index.js | 7 + .../lib/jsdom/level2/languages/javascript.js | 13 + node_modules/jsdom/lib/jsdom/level2/style.js | 236 ++ node_modules/jsdom/lib/jsdom/level3/core.js | 644 +++ node_modules/jsdom/lib/jsdom/level3/events.js | 299 ++ node_modules/jsdom/lib/jsdom/level3/html.js | 9 + node_modules/jsdom/lib/jsdom/level3/index.js | 10 + node_modules/jsdom/lib/jsdom/level3/ls.js | 221 ++ node_modules/jsdom/lib/jsdom/level3/xpath.js | 1859 +++++++++ .../jsdom/lib/jsdom/selectors/index.js | 39 + .../jsdom/lib/jsdom/selectors/sizzle.js | 1449 +++++++ node_modules/jsdom/lib/jsdom/utils.js | 27 + .../jsdom/node_modules/contextify/.npmignore | 12 + .../jsdom/node_modules/contextify/LICENSE.txt | 22 + .../jsdom/node_modules/contextify/README.md | 102 + .../jsdom/node_modules/contextify/binding.gyp | 8 + .../node_modules/contextify/build/Makefile | 359 ++ .../Release/.deps/Release/contextify.node.d | 1 + .../obj.target/contextify/src/contextify.o.d | 29 + .../contextify/build/Release/contextify.node | Bin 0 -> 27140 bytes .../contextify/build/Release/linker.lock | 0 .../obj.target/contextify/src/contextify.o | Bin 0 -> 117624 bytes .../contextify/build/binding.Makefile | 6 + .../node_modules/contextify/build/config.gypi | 103 + .../contextify/build/contextify.target.mk | 147 + .../contextify/build/gyp-mac-tool | 210 + .../jsdom/node_modules/contextify/changelog | 40 + .../node_modules/contextify/lib/contextify.js | 30 + .../node_modules/bindings/README.md | 97 + .../node_modules/bindings/bindings.js | 151 + .../node_modules/bindings/package.json | 30 + .../node_modules/contextify/package.json | 51 + .../node_modules/contextify/src/contextify.cc | 218 ++ .../contextify/test/contextify.js | 461 +++ .../jsdom/node_modules/contextify/wscript | 18 + .../jsdom/node_modules/cssom/.gitmodules | 6 + .../jsdom/node_modules/cssom/.npmignore | 7 + .../jsdom/node_modules/cssom/README.mdown | 34 + .../node_modules/cssom/lib/CSSFontFaceRule.js | 34 + .../node_modules/cssom/lib/CSSImportRule.js | 131 + .../node_modules/cssom/lib/CSSKeyframeRule.js | 35 + .../cssom/lib/CSSKeyframesRule.js | 37 + .../node_modules/cssom/lib/CSSMediaRule.js | 39 + .../jsdom/node_modules/cssom/lib/CSSRule.js | 39 + .../cssom/lib/CSSStyleDeclaration.js | 148 + .../node_modules/cssom/lib/CSSStyleRule.js | 189 + .../node_modules/cssom/lib/CSSStyleSheet.js | 87 + .../jsdom/node_modules/cssom/lib/MediaList.js | 61 + .../node_modules/cssom/lib/StyleSheet.js | 17 + .../jsdom/node_modules/cssom/lib/clone.js | 76 + .../jsdom/node_modules/cssom/lib/index.js | 15 + .../jsdom/node_modules/cssom/lib/parse.js | 338 ++ .../jsdom/node_modules/cssom/package.json | 48 + .../jsdom/node_modules/htmlparser/.project | 17 + .../node_modules/htmlparser/.project.bak | 17 + .../htmlparser/.settings/.jsdtscope | 6 + .../org.eclipse.core.resources.prefs | 3 + ...rg.eclipse.wst.jsdt.ui.superType.container | 1 + .../org.eclipse.wst.jsdt.ui.superType.name | 1 + .../jsdom/node_modules/htmlparser/CHANGELOG | 47 + .../jsdom/node_modules/htmlparser/LICENSE | 18 + .../jsdom/node_modules/htmlparser/README.md | 247 ++ node_modules/jsdom/node_modules/htmlparser/a | 20 + node_modules/jsdom/node_modules/htmlparser/b | 26 + node_modules/jsdom/node_modules/htmlparser/c | 35 + .../jsdom/node_modules/htmlparser/json2.js | 482 +++ .../node_modules/htmlparser/lib/htmlparser.js | 823 ++++ .../htmlparser/lib/htmlparser.min.js | 22 + .../htmlparser/lib/node-htmlparser.js | 6 + .../htmlparser/lib/node-htmlparser.min.js | 6 + .../node_modules/htmlparser/libxmljs.node | Bin 0 -> 102420 bytes .../jsdom/node_modules/htmlparser/new/a | 6 + .../jsdom/node_modules/htmlparser/new/b | 6 + .../node_modules/htmlparser/new/compat.js | 954 +++++ .../node_modules/htmlparser/new/htmlparser.js | 645 +++ .../node_modules/htmlparser/new/parser.zip | Bin 0 -> 6706 bytes .../node_modules/htmlparser/new/test01.js | 258 ++ .../node_modules/htmlparser/new/test02.js | 856 ++++ .../node_modules/htmlparser/newparser.js | 54 + .../htmlparser/node-htmlparser.old.js | 754 ++++ .../node_modules/htmlparser/package.json | 44 + .../jsdom/node_modules/htmlparser/profile | 4 + .../htmlparser/profile.getelement.js | 53 + .../htmlparser/profile.getelement.txt | 199 + .../jsdom/node_modules/htmlparser/profile.js | 63 + .../htmlparser/profileresults.txt | 301 ++ .../pulls/node-htmlparser/CHANGELOG | 9 + .../htmlparser/pulls/node-htmlparser/LICENSE | 18 + .../pulls/node-htmlparser/README.md | 186 + .../htmlparser/pulls/node-htmlparser/json2.js | 482 +++ .../node-htmlparser/lib/node-htmlparser.js | 772 ++++ .../lib/node-htmlparser.min.js | 22 + .../pulls/node-htmlparser/package.json | 23 + .../pulls/node-htmlparser/profile.js | 63 + .../pulls/node-htmlparser/runtests.html | 107 + .../pulls/node-htmlparser/runtests.js | 75 + .../pulls/node-htmlparser/runtests.min.html | 107 + .../pulls/node-htmlparser/runtests.min.js | 75 + .../pulls/node-htmlparser/snippet.js | 15 + .../pulls/node-htmlparser/tests/01-basic.js | 57 + .../node-htmlparser/tests/02-single_tag_1.js | 35 + .../node-htmlparser/tests/03-single_tag_2.js | 36 + .../tests/04-unescaped_in_script.js | 52 + .../tests/05-tags_in_comment.js | 44 + .../tests/06-comment_in_script.js | 44 + .../tests/07-unescaped_in_style.js | 45 + .../tests/08-extra_spaces_in_tag.js | 45 + .../tests/09-unquoted_attrib.js | 45 + .../tests/10-singular_attribute.js | 39 + .../tests/11-text_outside_tags.js | 46 + .../node-htmlparser/tests/12-text_only.js | 37 + .../tests/13-comment_in_text.js | 45 + .../tests/14-comment_in_text_in_script.js | 53 + .../node-htmlparser/tests/15-non-verbose.js | 43 + .../tests/16-ignore_whitespace.js | 68 + .../node-htmlparser/tests/17-xml_namespace.js | 34 + .../tests/18-enforce_empty_tags.js | 36 + .../tests/19-ignore_empty_tags.js | 38 + .../pulls/node-htmlparser/tests/20-rss.js | 117 + .../pulls/node-htmlparser/tests/21-atom.js | 77 + .../pulls/node-htmlparser/utils_example.js | 35 + .../jsdom/node_modules/htmlparser/rssbug.js | 16 + .../jsdom/node_modules/htmlparser/rssbug.rss | 1 + .../node_modules/htmlparser/runtests.html | 108 + .../jsdom/node_modules/htmlparser/runtests.js | 75 + .../node_modules/htmlparser/runtests.min.html | 108 + .../node_modules/htmlparser/runtests.min.js | 75 + .../node_modules/htmlparser/runtests_new.js | 75 + .../jsdom/node_modules/htmlparser/snippet.js | 15 + .../jsdom/node_modules/htmlparser/test01.js | 105 + .../htmlparser/testdata/.tmp_test.html.2854~ | 11 + .../testdata/.tmp_trackerchecker.html.65425~ | 2948 ++++++++++++++ .../testdata/.tmp_trackerchecker.html.76922~ | 10 + .../testdata/.tmp_trackerchecker.html.80022~ | 2948 ++++++++++++++ .../testdata/.tmp_trackerchecker2.html.51378~ | 2948 ++++++++++++++ .../testdata/.tmp_trackerchecker2.html.75287~ | 2947 ++++++++++++++ .../node_modules/htmlparser/testdata/api.html | 3311 ++++++++++++++++ .../htmlparser/testdata/getelement.html | 3460 +++++++++++++++++ .../htmlparser/testdata/trackerchecker.html | 2733 +++++++++++++ .../node_modules/htmlparser/tests/01-basic.js | 61 + .../htmlparser/tests/02-single_tag_1.js | 39 + .../htmlparser/tests/03-single_tag_2.js | 40 + .../tests/04-unescaped_in_script.js | 56 + .../htmlparser/tests/05-tags_in_comment.js | 48 + .../htmlparser/tests/06-comment_in_script.js | 48 + .../htmlparser/tests/07-unescaped_in_style.js | 49 + .../tests/08-extra_spaces_in_tag.js | 49 + .../htmlparser/tests/09-unquoted_attrib.js | 49 + .../htmlparser/tests/10-singular_attribute.js | 43 + .../htmlparser/tests/11-text_outside_tags.js | 50 + .../htmlparser/tests/12-text_only.js | 41 + .../htmlparser/tests/13-comment_in_text.js | 49 + .../tests/14-comment_in_text_in_script.js | 57 + .../htmlparser/tests/15-non-verbose.js | 46 + .../htmlparser/tests/16-ignore_whitespace.js | 71 + .../htmlparser/tests/17-xml_namespace.js | 38 + .../htmlparser/tests/18-enforce_empty_tags.js | 40 + .../htmlparser/tests/19-ignore_empty_tags.js | 41 + .../node_modules/htmlparser/tests/20-rss.js | 120 + .../node_modules/htmlparser/tests/21-atom.js | 80 + .../htmlparser/tests/22-position_data.js | 100 + .../node_modules/htmlparser/tmp/snippet.js | 13 + .../node_modules/htmlparser/utils_example.js | 35 + .../jsdom/node_modules/htmlparser/v8.log | 1956 ++++++++++ node_modules/jsdom/package.json | 203 + node_modules/jsdom/status.json | 22 + node_modules/mime/LICENSE | 19 + node_modules/mime/README.md | 63 + node_modules/mime/mime.js | 104 + node_modules/mime/package.json | 34 + node_modules/mime/test.js | 55 + node_modules/mime/types/mime.types | 1588 ++++++++ node_modules/mime/types/node.types | 59 + node_modules/node-static/.DS_Store | Bin 0 -> 6148 bytes node_modules/node-static/lib/node-static.js | 260 ++ .../node-static/lib/node-static/mime.js | 140 + .../node-static/lib/node-static/util.js | 30 + node_modules/node-static/package.json | 36 + node_modules/openurl/.npmignore | 3 + node_modules/openurl/README.md | 29 + node_modules/openurl/openurl.js | 68 + node_modules/openurl/package.json | 25 + node_modules/optimist/.travis.yml | 4 + node_modules/optimist/LICENSE | 21 + node_modules/optimist/README.markdown | 487 +++ node_modules/optimist/example/bool.js | 10 + .../optimist/example/boolean_double.js | 7 + .../optimist/example/boolean_single.js | 7 + node_modules/optimist/example/default_hash.js | 8 + .../optimist/example/default_singles.js | 7 + node_modules/optimist/example/divide.js | 8 + node_modules/optimist/example/line_count.js | 20 + .../optimist/example/line_count_options.js | 29 + .../optimist/example/line_count_wrap.js | 29 + node_modules/optimist/example/nonopt.js | 4 + node_modules/optimist/example/reflect.js | 2 + node_modules/optimist/example/short.js | 3 + node_modules/optimist/example/string.js | 11 + .../optimist/example/usage-options.js | 19 + node_modules/optimist/example/xup.js | 10 + node_modules/optimist/index.js | 475 +++ .../optimist/node_modules/wordwrap/.npmignore | 1 + .../node_modules/wordwrap/README.markdown | 70 + .../node_modules/wordwrap/example/center.js | 10 + .../node_modules/wordwrap/example/meat.js | 3 + .../optimist/node_modules/wordwrap/index.js | 76 + .../node_modules/wordwrap/package.json | 43 + .../node_modules/wordwrap/test/break.js | 30 + .../node_modules/wordwrap/test/idleness.txt | 63 + .../node_modules/wordwrap/test/wrap.js | 31 + node_modules/optimist/package.json | 49 + node_modules/optimist/test/_.js | 71 + node_modules/optimist/test/_/argv.js | 2 + node_modules/optimist/test/_/bin.js | 3 + node_modules/optimist/test/parse.js | 433 +++ node_modules/optimist/test/usage.js | 292 ++ node_modules/optimist/x.js | 1 + node_modules/request/LICENSE | 55 + node_modules/request/README.md | 309 ++ node_modules/request/aws.js | 190 + node_modules/request/forever.js | 103 + node_modules/request/main.js | 1096 ++++++ .../request/node_modules/form-data/.npmignore | 5 + .../request/node_modules/form-data/Makefile | 7 + .../request/node_modules/form-data/Readme.md | 86 + .../node_modules/form-data/lib/form_data.js | 237 ++ .../form-data/node-form-data.sublime-project | 8 + .../node-form-data.sublime-workspace | 508 +++ .../form-data/node_modules/async/.gitmodules | 9 + .../form-data/node_modules/async/LICENSE | 19 + .../form-data/node_modules/async/Makefile | 21 + .../form-data/node_modules/async/README.md | 970 +++++ .../node_modules/async/async.min.js.gzip | Bin 0 -> 1859 bytes .../node_modules/async/deps/nodeunit.css | 70 + .../node_modules/async/deps/nodeunit.js | 1966 ++++++++++ .../node_modules/async/dist/async.min.js | 1 + .../form-data/node_modules/async/index.js | 3 + .../form-data/node_modules/async/lib/async.js | 632 +++ .../form-data/node_modules/async/nodelint.cfg | 4 + .../form-data/node_modules/async/package.json | 41 + .../form-data/node_modules/async/test/.swp | Bin 0 -> 12288 bytes .../node_modules/async/test/test-async.js | 1367 +++++++ .../node_modules/async/test/test.html | 24 + .../node_modules/combined-stream/.npmignore | 3 + .../node_modules/combined-stream/License | 19 + .../node_modules/combined-stream/Makefile | 7 + .../node_modules/combined-stream/Readme.md | 132 + .../combined-stream/lib/combined_stream.js | 183 + .../node_modules/delayed-stream/.npmignore | 2 + .../node_modules/delayed-stream/License | 19 + .../node_modules/delayed-stream/Makefile | 7 + .../node_modules/delayed-stream/Readme.md | 154 + .../delayed-stream/lib/delayed_stream.js | 99 + .../node_modules/delayed-stream/package.json | 38 + .../delayed-stream/test/common.js | 6 + .../integration/test-delayed-http-upload.js | 38 + .../test-delayed-stream-auto-pause.js | 21 + .../integration/test-delayed-stream-pause.js | 14 + .../test/integration/test-delayed-stream.js | 48 + .../integration/test-handle-source-errors.js | 15 + .../test/integration/test-max-data-size.js | 18 + .../test/integration/test-pipe-resumes.js | 13 + .../test/integration/test-proxy-readable.js | 13 + .../node_modules/delayed-stream/test/run.js | 7 + .../node_modules/combined-stream/package.json | 39 + .../combined-stream/test/common.js | 12 + .../combined-stream/test/fixture/file1.txt | 256 ++ .../combined-stream/test/fixture/file2.txt | 256 ++ .../test/integration/test-callback-streams.js | 27 + .../test/integration/test-data-size.js | 34 + ...delayed-streams-and-buffers-and-strings.js | 38 + .../test/integration/test-delayed-streams.js | 35 + .../test/integration/test-max-data-size.js | 24 + .../test/integration/test-unpaused-streams.js | 30 + .../node_modules/combined-stream/test/run.js | 7 + .../node_modules/form-data/package.json | 43 + .../node_modules/form-data/test/common.js | 14 + .../form-data/test/fixture/bacon.txt | 1 + .../form-data/test/fixture/unicycle.jpg | Bin 0 -> 19806 bytes .../test/integration/test-form-get-length.js | 93 + .../test/integration/test-get-boundary.js | 18 + .../test/integration/test-http-response.js | 121 + .../form-data/test/integration/test-pipe.js | 111 + .../form-data/test/integration/test-submit.js | 107 + .../node_modules/form-data/test/run.js | 7 + .../request/node_modules/mime/LICENSE | 19 + .../request/node_modules/mime/README.md | 63 + .../request/node_modules/mime/mime.js | 104 + .../request/node_modules/mime/package.json | 42 + .../request/node_modules/mime/test.js | 55 + .../node_modules/mime/types/mime.types | 1588 ++++++++ .../node_modules/mime/types/node.types | 59 + node_modules/request/oauth.js | 34 + node_modules/request/package.json | 40 + node_modules/request/tests/googledoodle.png | Bin 0 -> 38510 bytes node_modules/request/tests/run.js | 45 + node_modules/request/tests/server.js | 86 + node_modules/request/tests/squid.conf | 77 + node_modules/request/tests/ssl/ca/ca.cnf | 20 + node_modules/request/tests/ssl/ca/ca.crl | 0 node_modules/request/tests/ssl/ca/ca.crt | 17 + node_modules/request/tests/ssl/ca/ca.csr | 13 + node_modules/request/tests/ssl/ca/ca.key | 18 + node_modules/request/tests/ssl/ca/ca.srl | 1 + node_modules/request/tests/ssl/ca/server.cnf | 19 + node_modules/request/tests/ssl/ca/server.crt | 16 + node_modules/request/tests/ssl/ca/server.csr | 11 + node_modules/request/tests/ssl/ca/server.js | 28 + node_modules/request/tests/ssl/ca/server.key | 9 + node_modules/request/tests/ssl/npm-ca.crt | 16 + node_modules/request/tests/ssl/test.crt | 15 + node_modules/request/tests/ssl/test.key | 15 + node_modules/request/tests/test-body.js | 117 + node_modules/request/tests/test-cookie.js | 29 + node_modules/request/tests/test-cookiejar.js | 90 + node_modules/request/tests/test-defaults.js | 99 + node_modules/request/tests/test-errors.js | 37 + .../request/tests/test-follow-all-303.js | 30 + node_modules/request/tests/test-follow-all.js | 35 + node_modules/request/tests/test-form.js | 79 + node_modules/request/tests/test-headers.js | 52 + node_modules/request/tests/test-httpModule.js | 94 + .../request/tests/test-https-strict.js | 97 + node_modules/request/tests/test-https.js | 86 + node_modules/request/tests/test-oauth.js | 117 + node_modules/request/tests/test-params.js | 92 + .../request/tests/test-piped-redirect.js | 52 + node_modules/request/tests/test-pipes.js | 202 + node_modules/request/tests/test-pool.js | 16 + .../tests/test-protocol-changing-redirect.js | 60 + node_modules/request/tests/test-proxy.js | 39 + node_modules/request/tests/test-qs.js | 28 + node_modules/request/tests/test-redirect.js | 154 + node_modules/request/tests/test-s3.js | 13 + node_modules/request/tests/test-timeout.js | 87 + node_modules/request/tests/test-toJSON.js | 14 + node_modules/request/tests/test-tunnel.js | 63 + node_modules/request/tests/unicycle.jpg | Bin 0 -> 19806 bytes node_modules/request/tunnel.js | 230 ++ node_modules/request/uuid.js | 19 + node_modules/request/vendor/cookie/index.js | 65 + node_modules/request/vendor/cookie/jar.js | 72 + node_modules/underscore/.npmignore | 3 + node_modules/underscore/CNAME | 1 + node_modules/underscore/CONTRIBUTING.md | 9 + node_modules/underscore/LICENSE | 22 + node_modules/underscore/README.md | 19 + node_modules/underscore/favicon.ico | Bin 0 -> 1406 bytes node_modules/underscore/index.html | 2356 +++++++++++ node_modules/underscore/index.js | 1 + node_modules/underscore/package.json | 28 + node_modules/underscore/raw/underscore.psd | Bin 0 -> 215540 bytes node_modules/underscore/underscore-min.js | 5 + node_modules/underscore/underscore.js | 1189 ++++++ node_modules/websocket-server/.npmignore | 1 + node_modules/websocket-server/LICENSE.md | 21 + node_modules/websocket-server/Makefile | 27 + node_modules/websocket-server/README.md | 7 + node_modules/websocket-server/docs/index.html | 386 ++ node_modules/websocket-server/docs/style.css | 287 ++ node_modules/websocket-server/lib/_events.js | 26 + node_modules/websocket-server/lib/_util.js | 1 + .../websocket-server/lib/lang/mixin.js | 12 + .../websocket-server/lib/ws/connection.js | 523 +++ .../websocket-server/lib/ws/manager.js | 159 + .../websocket-server/lib/ws/parser.js | 141 + .../websocket-server/lib/ws/server.js | 109 + node_modules/websocket-server/package.json | 33 + .../samples/handshake-packets | 104 + node_modules/websocket-server/test/common.js | 0 .../websocket-server/test/fixtures/.npmignore | 0 .../test/manual/chat-server.js | 67 + .../websocket-server/test/manual/chat.html | 93 + .../websocket-server/test/manual/client.html | 143 + .../test/manual/dev-server.js | 123 + .../test/manual/echo-server.js | 27 + .../websocket-server/test/manual/ssl/cert.key | 15 + .../websocket-server/test/manual/ssl/cert.pem | 22 + .../test/manual/test-https-upgrade.js | 103 + .../websocket-server/test/pummel/.npmignore | 0 .../websocket-server/test/simple/.npmignore | 0 .../websocket-server/tools/release.js | 33 + node_modules/websocket/CHANGELOG.md | 71 + node_modules/websocket/LICENSE | 177 + node_modules/websocket/Makefile | 11 + node_modules/websocket/README.md | 240 ++ node_modules/websocket/binding.gyp | 14 + node_modules/websocket/build/Makefile | 364 ++ .../obj.target/validation/src/validation.o.d | 31 + .../.deps/Release/obj.target/xor/src/xor.o.d | 31 + .../Release/.deps/Release/validation.node.d | 1 + .../build/Release/.deps/Release/xor.node.d | 1 + .../websocket/build/Release/linker.lock | 0 .../obj.target/validation/src/validation.o | Bin 0 -> 71292 bytes .../build/Release/obj.target/xor/src/xor.o | Bin 0 -> 57960 bytes .../websocket/build/Release/validation.node | Bin 0 -> 18204 bytes node_modules/websocket/build/Release/xor.node | Bin 0 -> 13208 bytes node_modules/websocket/build/binding.Makefile | 6 + node_modules/websocket/build/config.gypi | 103 + node_modules/websocket/build/gyp-mac-tool | 210 + .../websocket/build/validation.target.mk | 147 + node_modules/websocket/build/xor.target.mk | 147 + node_modules/websocket/index.js | 1 + node_modules/websocket/install.js | 28 + node_modules/websocket/lib/Constants.js | 23 + .../websocket/lib/Validation.fallback.js | 12 + node_modules/websocket/lib/Validation.js | 18 + node_modules/websocket/lib/WebSocketClient.js | 325 ++ .../websocket/lib/WebSocketConnection.js | 707 ++++ node_modules/websocket/lib/WebSocketFrame.js | 282 ++ .../websocket/lib/WebSocketRequest.js | 428 ++ node_modules/websocket/lib/WebSocketRouter.js | 154 + .../websocket/lib/WebSocketRouterRequest.js | 52 + node_modules/websocket/lib/WebSocketServer.js | 206 + node_modules/websocket/lib/utils.js | 7 + node_modules/websocket/lib/websocket.js | 10 + node_modules/websocket/lib/xor.fallback.js | 13 + node_modules/websocket/lib/xor.js | 18 + node_modules/websocket/package.json | 37 + node_modules/websocket/src/validation.cc | 144 + node_modules/websocket/src/xor.cpp | 86 + .../websocket/vendor/FastBufferList.js | 192 + .../websocket/vendor/node-ctype/LICENSE | 18 + .../vendor/node-ctype/ctio-faster.js | 1126 ++++++ public/.DS_Store | Bin 0 -> 6148 bytes public/body-bg.png | Bin 0 -> 65481 bytes public/body-bg2.jpg | Bin 0 -> 167439 bytes public/button-bg.gif | Bin 0 -> 463 bytes public/classes.js | 1146 ++++++ public/date.format.js | 126 + public/dock-bg.gif | Bin 0 -> 173 bytes public/emoticons.xml | 911 +++++ .../PT Mono SIL OFL Font License 1.1.txt | 93 + public/fonts/PTM55FT-webfont.eot | Bin 0 -> 35674 bytes public/fonts/PTM55FT-webfont.svg | 259 ++ public/fonts/PTM55FT-webfont.ttf | Bin 0 -> 35480 bytes public/fonts/PTM55FT-webfont.woff | Bin 0 -> 23300 bytes public/fonts/demo.html | 33 + public/fonts/pt-mono-fontfacekit.zip | Bin 0 -> 91806 bytes public/fonts/stylesheet.css | 16 + public/images/.DS_Store | Bin 0 -> 6148 bytes public/images/emoticons/1.gif | Bin 0 -> 1197 bytes public/images/emoticons/10.gif | Bin 0 -> 845 bytes public/images/emoticons/100.gif | Bin 0 -> 3606 bytes public/images/emoticons/101.gif | Bin 0 -> 3611 bytes public/images/emoticons/102.gif | Bin 0 -> 6180 bytes public/images/emoticons/103.gif | Bin 0 -> 2384 bytes public/images/emoticons/104.gif | Bin 0 -> 8282 bytes public/images/emoticons/105.gif | Bin 0 -> 1342 bytes public/images/emoticons/106.gif | Bin 0 -> 6445 bytes public/images/emoticons/107.gif | Bin 0 -> 8402 bytes public/images/emoticons/108.gif | Bin 0 -> 4091 bytes public/images/emoticons/109.gif | Bin 0 -> 3349 bytes public/images/emoticons/11.gif | Bin 0 -> 1317 bytes public/images/emoticons/110.gif | Bin 0 -> 6256 bytes public/images/emoticons/111.gif | Bin 0 -> 7031 bytes public/images/emoticons/112.gif | Bin 0 -> 3962 bytes public/images/emoticons/113.gif | Bin 0 -> 4038 bytes public/images/emoticons/114.gif | Bin 0 -> 10381 bytes public/images/emoticons/115.gif | Bin 0 -> 5258 bytes public/images/emoticons/12.gif | Bin 0 -> 2318 bytes public/images/emoticons/13.gif | Bin 0 -> 1668 bytes public/images/emoticons/14.gif | Bin 0 -> 4770 bytes public/images/emoticons/15.gif | Bin 0 -> 809 bytes public/images/emoticons/16.gif | Bin 0 -> 1017 bytes public/images/emoticons/17.gif | Bin 0 -> 1203 bytes public/images/emoticons/18.gif | Bin 0 -> 4268 bytes public/images/emoticons/19.gif | Bin 0 -> 4005 bytes public/images/emoticons/2.gif | Bin 0 -> 1001 bytes public/images/emoticons/20.gif | Bin 0 -> 2304 bytes public/images/emoticons/21.gif | Bin 0 -> 646 bytes public/images/emoticons/22.gif | Bin 0 -> 613 bytes public/images/emoticons/23.gif | Bin 0 -> 821 bytes public/images/emoticons/24.gif | Bin 0 -> 11360 bytes public/images/emoticons/25.gif | Bin 0 -> 7815 bytes public/images/emoticons/26.gif | Bin 0 -> 1976 bytes public/images/emoticons/27.gif | Bin 0 -> 1212 bytes public/images/emoticons/28.gif | Bin 0 -> 1328 bytes public/images/emoticons/29.gif | Bin 0 -> 977 bytes public/images/emoticons/3.gif | Bin 0 -> 1001 bytes public/images/emoticons/30.gif | Bin 0 -> 1715 bytes public/images/emoticons/31.gif | Bin 0 -> 1819 bytes public/images/emoticons/32.gif | Bin 0 -> 2713 bytes public/images/emoticons/33.gif | Bin 0 -> 1014 bytes public/images/emoticons/34.gif | Bin 0 -> 3435 bytes public/images/emoticons/35.gif | Bin 0 -> 2584 bytes public/images/emoticons/36.gif | Bin 0 -> 3932 bytes public/images/emoticons/37.gif | Bin 0 -> 1811 bytes public/images/emoticons/38.gif | Bin 0 -> 595 bytes public/images/emoticons/39.gif | Bin 0 -> 987 bytes public/images/emoticons/4.gif | Bin 0 -> 536 bytes public/images/emoticons/40.gif | Bin 0 -> 1327 bytes public/images/emoticons/41.gif | Bin 0 -> 1287 bytes public/images/emoticons/42.gif | Bin 0 -> 2170 bytes public/images/emoticons/43.gif | Bin 0 -> 613 bytes public/images/emoticons/44.gif | Bin 0 -> 975 bytes public/images/emoticons/45.gif | Bin 0 -> 1649 bytes public/images/emoticons/46.gif | Bin 0 -> 1515 bytes public/images/emoticons/47.gif | Bin 0 -> 781 bytes public/images/emoticons/48.gif | Bin 0 -> 1831 bytes public/images/emoticons/49.gif | Bin 0 -> 1412 bytes public/images/emoticons/5.gif | Bin 0 -> 1146 bytes public/images/emoticons/50.gif | Bin 0 -> 1912 bytes public/images/emoticons/51.gif | Bin 0 -> 1195 bytes public/images/emoticons/52.gif | Bin 0 -> 814 bytes public/images/emoticons/53.gif | Bin 0 -> 263 bytes public/images/emoticons/54.gif | Bin 0 -> 377 bytes public/images/emoticons/55.gif | Bin 0 -> 1891 bytes public/images/emoticons/56.gif | Bin 0 -> 1472 bytes public/images/emoticons/57.gif | Bin 0 -> 1129 bytes public/images/emoticons/58.gif | Bin 0 -> 1802 bytes public/images/emoticons/59.gif | Bin 0 -> 2702 bytes public/images/emoticons/6.gif | Bin 0 -> 3488 bytes public/images/emoticons/60.gif | Bin 0 -> 1872 bytes public/images/emoticons/61.gif | Bin 0 -> 1699 bytes public/images/emoticons/62.gif | Bin 0 -> 406 bytes public/images/emoticons/63.gif | Bin 0 -> 2183 bytes public/images/emoticons/64.gif | Bin 0 -> 1050 bytes public/images/emoticons/65.gif | Bin 0 -> 3010 bytes public/images/emoticons/66.gif | Bin 0 -> 5857 bytes public/images/emoticons/67.gif | Bin 0 -> 2669 bytes public/images/emoticons/68.gif | Bin 0 -> 2538 bytes public/images/emoticons/69.gif | Bin 0 -> 3448 bytes public/images/emoticons/7.gif | Bin 0 -> 2728 bytes public/images/emoticons/70.gif | Bin 0 -> 2070 bytes public/images/emoticons/71.gif | Bin 0 -> 3870 bytes public/images/emoticons/72.gif | Bin 0 -> 409 bytes public/images/emoticons/73.gif | Bin 0 -> 471 bytes public/images/emoticons/74.gif | Bin 0 -> 449 bytes public/images/emoticons/75.gif | Bin 0 -> 414 bytes public/images/emoticons/76.gif | Bin 0 -> 6207 bytes public/images/emoticons/77.gif | Bin 0 -> 2867 bytes public/images/emoticons/78.gif | Bin 0 -> 4341 bytes public/images/emoticons/79.gif | Bin 0 -> 981 bytes public/images/emoticons/8.gif | Bin 0 -> 2323 bytes public/images/emoticons/9.gif | Bin 0 -> 1641 bytes public/images/emoticons/Emoticons.plist | 913 +++++ public/images/emoticons/pirate.gif | Bin 0 -> 1156 bytes public/images/emoticons/test.txt | 1 + public/images/emoticons/transformer.gif | Bin 0 -> 1154 bytes public/images/ew.gif | Bin 0 -> 246 bytes public/images/resize.gif | Bin 0 -> 868 bytes public/index.html | 111 + public/main.css | 386 ++ public/main.js | 341 ++ public/plist_parser.js | 226 ++ public/pwc-os.js | 103 + public/resize.gif | 11 + public/server.js | 36 + public/windows_js_1.3/MIT-LICENSE | 19 + public/windows_js_1.3/PWC-OS/body-bg.png | Bin 0 -> 65481 bytes public/windows_js_1.3/PWC-OS/button-bg.gif | Bin 0 -> 463 bytes public/windows_js_1.3/PWC-OS/dock-bg.gif | Bin 0 -> 173 bytes public/windows_js_1.3/PWC-OS/index.html | 37 + public/windows_js_1.3/PWC-OS/pwc-os.css | 36 + public/windows_js_1.3/PWC-OS/pwc-os.js | 103 + public/windows_js_1.3/README | 182 + .../documentation/PWC-OS/body-bg.png | Bin 0 -> 65481 bytes .../documentation/PWC-OS/button-bg.gif | Bin 0 -> 463 bytes .../documentation/PWC-OS/dock-bg.gif | Bin 0 -> 173 bytes .../documentation/PWC-OS/index.html | 37 + .../documentation/PWC-OS/pwc-os.css | 36 + .../documentation/PWC-OS/pwc-os.js | 103 + .../windows_js_1.3/documentation/debug.html | 109 + .../documentation/documentation.html | 544 +++ .../documentation/info_panel.html | 31 + .../documentation/javascripts/debug.js | 137 + .../documentation/javascripts/effects.js | 1094 ++++++ .../javascripts/extended_debug.js | 113 + .../documentation/javascripts/prototype.js | 3269 ++++++++++++++++ .../documentation/javascripts/tooltip.js | 241 ++ .../documentation/javascripts/window.js | 1843 +++++++++ .../javascripts/window_effects.js | 157 + .../documentation/javascripts/window_ext.js | 115 + .../documentation/js/application.js | 173 + public/windows_js_1.3/documentation/logo.gif | Bin 0 -> 3452 bytes public/windows_js_1.3/documentation/pwc.gif | Bin 0 -> 2495 bytes .../documentation/pwc_os_thumb.png | Bin 0 -> 31374 bytes .../windows_js_1.3/documentation/samples.html | 275 ++ .../documentation/stylesheets/login.css | 25 + .../documentation/stylesheets/style.css | 332 ++ .../windows_js_1.3/documentation/themes.html | 192 + .../documentation/themes/alert.css | 119 + .../documentation/themes/alert/bottom.gif | Bin 0 -> 70 bytes .../themes/alert/bottom_left.gif | Bin 0 -> 49 bytes .../themes/alert/bottom_right.gif | Bin 0 -> 49 bytes .../documentation/themes/alert/left.gif | Bin 0 -> 84 bytes .../documentation/themes/alert/overlay.png | Bin 0 -> 2829 bytes .../documentation/themes/alert/progress.gif | Bin 0 -> 1542 bytes .../documentation/themes/alert/right.gif | Bin 0 -> 84 bytes .../documentation/themes/alert/top.gif | Bin 0 -> 70 bytes .../documentation/themes/alert/top_left.gif | Bin 0 -> 49 bytes .../documentation/themes/alert/top_right.gif | Bin 0 -> 49 bytes .../documentation/themes/alert_lite.css | 88 + .../documentation/themes/alphacube.css | 150 + .../themes/alphacube/bottom-left-c.gif | Bin 0 -> 60 bytes .../themes/alphacube/bottom-middle.gif | Bin 0 -> 50 bytes .../themes/alphacube/bottom-right-c.gif | Bin 0 -> 61 bytes .../themes/alphacube/button-close-focus.gif | Bin 0 -> 699 bytes .../themes/alphacube/button-max-focus.gif | Bin 0 -> 765 bytes .../themes/alphacube/button-min-focus.gif | Bin 0 -> 472 bytes .../themes/alphacube/frame-left.gif | Bin 0 -> 64 bytes .../themes/alphacube/frame-right.gif | Bin 0 -> 64 bytes .../themes/alphacube/left-top.gif | Bin 0 -> 171 bytes .../themes/alphacube/right-top.gif | Bin 0 -> 168 bytes .../themes/alphacube/top-middle.gif | Bin 0 -> 97 bytes .../documentation/themes/behavior.htc | 51 + .../documentation/themes/darkX.css | 121 + .../themes/darkX/button-close-focused.png | Bin 0 -> 904 bytes .../themes/darkX/button-maximize-focused.png | Bin 0 -> 882 bytes .../themes/darkX/button-minimize-focused.png | Bin 0 -> 839 bytes .../darkX/frame-bottom-left-focused.png | Bin 0 -> 142 bytes .../themes/darkX/frame-bottom-mid-focused.png | Bin 0 -> 142 bytes .../darkX/frame-bottom-right-focused.png | Bin 0 -> 142 bytes .../themes/darkX/frame-left-focused.png | Bin 0 -> 142 bytes .../themes/darkX/frame-right-focused.png | Bin 0 -> 142 bytes .../themes/darkX/titlebar-left-focused.png | Bin 0 -> 180 bytes .../themes/darkX/titlebar-mid-focused.png | Bin 0 -> 175 bytes .../themes/darkX/titlebar-right-focused.png | Bin 0 -> 180 bytes .../documentation/themes/debug.css | 25 + .../documentation/themes/default.css | 155 + .../themes/default/bottom_left.gif | Bin 0 -> 187 bytes .../themes/default/bottom_mid.gif | Bin 0 -> 68 bytes .../themes/default/bottom_right.gif | Bin 0 -> 187 bytes .../themes/default/bottom_right_resize.gif | Bin 0 -> 201 bytes .../themes/default/center_left.gif | Bin 0 -> 52 bytes .../themes/default/center_right.gif | Bin 0 -> 49 bytes .../documentation/themes/default/clear.gif | Bin 0 -> 1014 bytes .../documentation/themes/default/close.gif | Bin 0 -> 1012 bytes .../documentation/themes/default/inspect.gif | Bin 0 -> 556 bytes .../documentation/themes/default/maximize.gif | Bin 0 -> 1024 bytes .../documentation/themes/default/minimize.gif | Bin 0 -> 1023 bytes .../documentation/themes/default/overlay.png | Bin 0 -> 2818 bytes .../documentation/themes/default/resize.gif | Bin 0 -> 138 bytes .../documentation/themes/default/sizer.gif | Bin 0 -> 201 bytes .../documentation/themes/default/top_left.gif | Bin 0 -> 358 bytes .../documentation/themes/default/top_mid.gif | Bin 0 -> 149 bytes .../themes/default/top_right.gif | Bin 0 -> 357 bytes .../documentation/themes/iefix/blank.gif | Bin 0 -> 49 bytes .../documentation/themes/iefix/iepngfix.css | 3 + .../documentation/themes/iefix/iepngfix.htc | 54 + .../documentation/themes/lighting.css | 960 +++++ .../themes/lighting/background_buttons.gif | Bin 0 -> 70 bytes .../themes/lighting/bottom-left-blue.png | Bin 0 -> 335 bytes .../themes/lighting/bottom-left-darkblue.png | Bin 0 -> 334 bytes .../themes/lighting/bottom-left-green.png | Bin 0 -> 347 bytes .../themes/lighting/bottom-left-grey.png | Bin 0 -> 346 bytes .../themes/lighting/bottom-middle-blue.png | Bin 0 -> 156 bytes .../lighting/bottom-middle-darkblue.png | Bin 0 -> 154 bytes .../themes/lighting/bottom-middle-green.png | Bin 0 -> 155 bytes .../themes/lighting/bottom-middle-grey.png | Bin 0 -> 156 bytes .../themes/lighting/bottom-right-blue.png | Bin 0 -> 397 bytes .../themes/lighting/bottom-right-darkblue.png | Bin 0 -> 392 bytes .../themes/lighting/bottom-right-green.png | Bin 0 -> 390 bytes .../themes/lighting/bottom-right-grey.png | Bin 0 -> 424 bytes .../themes/lighting/button-close-blue.png | Bin 0 -> 308 bytes .../themes/lighting/button-close-darkblue.png | Bin 0 -> 308 bytes .../themes/lighting/button-close-green.png | Bin 0 -> 305 bytes .../themes/lighting/button-close-grey.png | Bin 0 -> 320 bytes .../themes/lighting/button-maximize-blue.png | Bin 0 -> 218 bytes .../lighting/button-maximize-darkblue.png | Bin 0 -> 212 bytes .../themes/lighting/button-maximize-green.png | Bin 0 -> 226 bytes .../themes/lighting/button-maximize-grey.png | Bin 0 -> 218 bytes .../themes/lighting/button-minimize-blue.png | Bin 0 -> 164 bytes .../lighting/button-minimize-darkblue.png | Bin 0 -> 172 bytes .../themes/lighting/button-minimize-green.png | Bin 0 -> 172 bytes .../themes/lighting/button-minimize-grey.png | Bin 0 -> 184 bytes .../themes/lighting/left-blue.png | Bin 0 -> 144 bytes .../themes/lighting/left-darkblue.png | Bin 0 -> 143 bytes .../themes/lighting/left-green.png | Bin 0 -> 144 bytes .../themes/lighting/left-grey.png | Bin 0 -> 144 bytes .../themes/lighting/pngbehavior.htc | 67 + .../themes/lighting/right-blue.png | Bin 0 -> 146 bytes .../themes/lighting/right-darkblue.png | Bin 0 -> 146 bytes .../themes/lighting/right-green.png | Bin 0 -> 146 bytes .../themes/lighting/right-grey.png | Bin 0 -> 155 bytes .../documentation/themes/lighting/spinner.gif | Bin 0 -> 2037 bytes .../themes/lighting/top-left-blue.png | Bin 0 -> 336 bytes .../themes/lighting/top-left-darkblue.png | Bin 0 -> 360 bytes .../themes/lighting/top-left-green.png | Bin 0 -> 339 bytes .../themes/lighting/top-left-grey.png | Bin 0 -> 352 bytes .../themes/lighting/top-middle-blue.png | Bin 0 -> 200 bytes .../themes/lighting/top-middle-darkblue.png | Bin 0 -> 226 bytes .../themes/lighting/top-middle-green.png | Bin 0 -> 208 bytes .../themes/lighting/top-middle-grey.png | Bin 0 -> 185 bytes .../themes/lighting/top-right-blue.png | Bin 0 -> 423 bytes .../themes/lighting/top-right-darkblue.png | Bin 0 -> 451 bytes .../themes/lighting/top-right-green.png | Bin 0 -> 440 bytes .../themes/lighting/top-right-grey.png | Bin 0 -> 495 bytes .../documentation/themes/mac_os_x.css | 333 ++ .../documentation/themes/mac_os_x/B.png | Bin 0 -> 268 bytes .../documentation/themes/mac_os_x/BL.png | Bin 0 -> 5068 bytes .../documentation/themes/mac_os_x/BL_Main.png | Bin 0 -> 5068 bytes .../documentation/themes/mac_os_x/BR.png | Bin 0 -> 5068 bytes .../documentation/themes/mac_os_x/BR_Main.png | Bin 0 -> 5068 bytes .../documentation/themes/mac_os_x/B_Main.png | Bin 0 -> 268 bytes .../documentation/themes/mac_os_x/L.png | Bin 0 -> 133 bytes .../documentation/themes/mac_os_x/L_Main.png | Bin 0 -> 133 bytes .../documentation/themes/mac_os_x/R.png | Bin 0 -> 133 bytes .../documentation/themes/mac_os_x/R_Main.png | Bin 0 -> 133 bytes .../documentation/themes/mac_os_x/T.png | Bin 0 -> 218 bytes .../documentation/themes/mac_os_x/TL.png | Bin 0 -> 360 bytes .../documentation/themes/mac_os_x/TL_Main.png | Bin 0 -> 444 bytes .../documentation/themes/mac_os_x/TR.png | Bin 0 -> 3818 bytes .../documentation/themes/mac_os_x/TR_Main.png | Bin 0 -> 3818 bytes .../documentation/themes/mac_os_x/T_Main.png | Bin 0 -> 218 bytes .../documentation/themes/mac_os_x/close.gif | Bin 0 -> 1012 bytes .../themes/mac_os_x/maximize.gif | Bin 0 -> 1024 bytes .../themes/mac_os_x/minimize.gif | Bin 0 -> 1023 bytes .../documentation/themes/mac_os_x_dialog.css | 160 + .../themes/mac_os_x_dialog/B.png | Bin 0 -> 2861 bytes .../themes/mac_os_x_dialog/BL.png | Bin 0 -> 3046 bytes .../themes/mac_os_x_dialog/BR.png | Bin 0 -> 3073 bytes .../themes/mac_os_x_dialog/L.png | Bin 0 -> 133 bytes .../themes/mac_os_x_dialog/R.png | Bin 0 -> 133 bytes .../themes/mac_os_x_dialog/T.png | Bin 0 -> 218 bytes .../themes/mac_os_x_dialog/TL.png | Bin 0 -> 360 bytes .../themes/mac_os_x_dialog/TR.png | Bin 0 -> 3818 bytes .../themes/mac_os_x_dialog/bg.gif | Bin 0 -> 65 bytes .../themes/mac_os_x_dialog/close.gif | Bin 0 -> 1012 bytes .../themes/mac_os_x_dialog/maximize.gif | Bin 0 -> 1024 bytes .../themes/mac_os_x_dialog/minimize.gif | Bin 0 -> 1023 bytes .../documentation/themes/nuncio.css | 164 + .../themes/nuncio/bottom_left.png | Bin 0 -> 616 bytes .../themes/nuncio/bottom_mid.png | Bin 0 -> 3617 bytes .../themes/nuncio/bottom_right.png | Bin 0 -> 660 bytes .../themes/nuncio/center_left.png | Bin 0 -> 6606 bytes .../themes/nuncio/center_right.png | Bin 0 -> 6509 bytes .../documentation/themes/nuncio/close.png | Bin 0 -> 772 bytes .../documentation/themes/nuncio/minimize.png | Bin 0 -> 693 bytes .../documentation/themes/nuncio/overlay.png | Bin 0 -> 40803 bytes .../documentation/themes/nuncio/top_left.png | Bin 0 -> 971 bytes .../documentation/themes/nuncio/top_mid.png | Bin 0 -> 5944 bytes .../documentation/themes/nuncio/top_right.png | Bin 0 -> 1245 bytes .../documentation/themes/spread.css | 108 + .../documentation/themes/spread/.gif | Bin 0 -> 2866 bytes .../themes/spread/bottom-left-c.gif | Bin 0 -> 60 bytes .../themes/spread/bottom-middle.gif | Bin 0 -> 50 bytes .../themes/spread/bottom-right-c.gif | Bin 0 -> 61 bytes .../themes/spread/button-close-focus.gif | Bin 0 -> 699 bytes .../themes/spread/button-max-focus.gif | Bin 0 -> 765 bytes .../themes/spread/button-min-focus.gif | Bin 0 -> 472 bytes .../themes/spread/frame-left.gif | Bin 0 -> 64 bytes .../themes/spread/frame-right.gif | Bin 0 -> 64 bytes .../documentation/themes/spread/left-top.gif | Bin 0 -> 273 bytes .../documentation/themes/spread/right-top.gif | Bin 0 -> 265 bytes .../themes/spread/top-middle.gif | Bin 0 -> 152 bytes .../helper/prototype_window_class_helper.rb | 58 + public/windows_js_1.3/javascripts/debug.js | 137 + public/windows_js_1.3/javascripts/effects.js | 1094 ++++++ .../javascripts/extended_debug.js | 113 + .../windows_js_1.3/javascripts/prototype.js | 3269 ++++++++++++++++ public/windows_js_1.3/javascripts/tooltip.js | 241 ++ public/windows_js_1.3/javascripts/window.js | 1843 +++++++++ .../javascripts/window_effects.js | 157 + .../windows_js_1.3/javascripts/window_ext.js | 115 + public/windows_js_1.3/samples/constraint.html | 83 + public/windows_js_1.3/samples/dialog.html | 51 + .../windows_js_1.3/samples/dialog_ajax.html | 4 + public/windows_js_1.3/samples/inframe.html | 54 + public/windows_js_1.3/samples/inset.html | 11 + .../windows_js_1.3/samples/multi_modal.html | 84 + .../samples/oldFirstSampleCode.html | 198 + public/windows_js_1.3/samples/openInside.html | 61 + public/windows_js_1.3/samples/parent.html | 37 + public/windows_js_1.3/samples/popup_open.html | 61 + public/windows_js_1.3/samples/rico/index.html | 73 + .../samples/rico/properties_1.gif | Bin 0 -> 896 bytes public/windows_js_1.3/samples/rico/rico.css | 30 + .../samples/rico/rico_change.js | 2818 ++++++++++++++ .../samples/tooltips/tooltip.html | 79 + .../samples/tooltips/tooltip_ajax.html | 4 + .../samples/tooltips/tooltip_url.html | 21 + public/windows_js_1.3/samples/window_key.html | 38 + .../samples/window_key_url_content.html | 22 + .../windows_js_1.3/samples/window_store.html | 51 + public/windows_js_1.3/themes/alert.css | 119 + public/windows_js_1.3/themes/alert/bottom.gif | Bin 0 -> 70 bytes .../themes/alert/bottom_left.gif | Bin 0 -> 49 bytes .../themes/alert/bottom_right.gif | Bin 0 -> 49 bytes public/windows_js_1.3/themes/alert/left.gif | Bin 0 -> 84 bytes .../windows_js_1.3/themes/alert/overlay.png | Bin 0 -> 2829 bytes .../windows_js_1.3/themes/alert/progress.gif | Bin 0 -> 1542 bytes public/windows_js_1.3/themes/alert/right.gif | Bin 0 -> 84 bytes public/windows_js_1.3/themes/alert/top.gif | Bin 0 -> 70 bytes .../windows_js_1.3/themes/alert/top_left.gif | Bin 0 -> 49 bytes .../windows_js_1.3/themes/alert/top_right.gif | Bin 0 -> 49 bytes public/windows_js_1.3/themes/alert_lite.css | 88 + public/windows_js_1.3/themes/alphacube.css | 150 + .../themes/alphacube/bottom-left-c.gif | Bin 0 -> 60 bytes .../themes/alphacube/bottom-middle.gif | Bin 0 -> 50 bytes .../themes/alphacube/bottom-right-c.gif | Bin 0 -> 61 bytes .../themes/alphacube/button-close-focus.gif | Bin 0 -> 699 bytes .../themes/alphacube/button-max-focus.gif | Bin 0 -> 765 bytes .../themes/alphacube/button-min-focus.gif | Bin 0 -> 472 bytes .../themes/alphacube/frame-left.gif | Bin 0 -> 64 bytes .../themes/alphacube/frame-right.gif | Bin 0 -> 64 bytes .../themes/alphacube/left-top.gif | Bin 0 -> 171 bytes .../themes/alphacube/right-top.gif | Bin 0 -> 168 bytes .../themes/alphacube/top-middle.gif | Bin 0 -> 97 bytes public/windows_js_1.3/themes/behavior.htc | 51 + public/windows_js_1.3/themes/darkX.css | 121 + .../themes/darkX/button-close-focused.png | Bin 0 -> 904 bytes .../themes/darkX/button-maximize-focused.png | Bin 0 -> 882 bytes .../themes/darkX/button-minimize-focused.png | Bin 0 -> 839 bytes .../darkX/frame-bottom-left-focused.png | Bin 0 -> 142 bytes .../themes/darkX/frame-bottom-mid-focused.png | Bin 0 -> 142 bytes .../darkX/frame-bottom-right-focused.png | Bin 0 -> 142 bytes .../themes/darkX/frame-left-focused.png | Bin 0 -> 142 bytes .../themes/darkX/frame-right-focused.png | Bin 0 -> 142 bytes .../themes/darkX/titlebar-left-focused.png | Bin 0 -> 180 bytes .../themes/darkX/titlebar-mid-focused.png | Bin 0 -> 175 bytes .../themes/darkX/titlebar-right-focused.png | Bin 0 -> 180 bytes public/windows_js_1.3/themes/debug.css | 25 + public/windows_js_1.3/themes/default.css | 155 + .../themes/default/bottom_left.gif | Bin 0 -> 187 bytes .../themes/default/bottom_mid.gif | Bin 0 -> 68 bytes .../themes/default/bottom_right.gif | Bin 0 -> 187 bytes .../themes/default/bottom_right_resize.gif | Bin 0 -> 201 bytes .../themes/default/center_left.gif | Bin 0 -> 52 bytes .../themes/default/center_right.gif | Bin 0 -> 49 bytes .../windows_js_1.3/themes/default/clear.gif | Bin 0 -> 1014 bytes .../windows_js_1.3/themes/default/close.gif | Bin 0 -> 1012 bytes .../windows_js_1.3/themes/default/inspect.gif | Bin 0 -> 556 bytes .../themes/default/maximize.gif | Bin 0 -> 1024 bytes .../themes/default/minimize.gif | Bin 0 -> 1023 bytes .../windows_js_1.3/themes/default/overlay.png | Bin 0 -> 2818 bytes .../windows_js_1.3/themes/default/resize.gif | Bin 0 -> 138 bytes .../windows_js_1.3/themes/default/sizer.gif | Bin 0 -> 201 bytes .../themes/default/top_left.gif | Bin 0 -> 358 bytes .../windows_js_1.3/themes/default/top_mid.gif | Bin 0 -> 149 bytes .../themes/default/top_right.gif | Bin 0 -> 357 bytes public/windows_js_1.3/themes/iefix/blank.gif | Bin 0 -> 49 bytes .../windows_js_1.3/themes/iefix/iepngfix.css | 3 + .../windows_js_1.3/themes/iefix/iepngfix.htc | 54 + public/windows_js_1.3/themes/lighting.css | 960 +++++ .../themes/lighting/background_buttons.gif | Bin 0 -> 70 bytes .../themes/lighting/bottom-left-blue.png | Bin 0 -> 335 bytes .../themes/lighting/bottom-left-darkblue.png | Bin 0 -> 334 bytes .../themes/lighting/bottom-left-green.png | Bin 0 -> 347 bytes .../themes/lighting/bottom-left-grey.png | Bin 0 -> 346 bytes .../themes/lighting/bottom-middle-blue.png | Bin 0 -> 156 bytes .../lighting/bottom-middle-darkblue.png | Bin 0 -> 154 bytes .../themes/lighting/bottom-middle-green.png | Bin 0 -> 155 bytes .../themes/lighting/bottom-middle-grey.png | Bin 0 -> 156 bytes .../themes/lighting/bottom-right-blue.png | Bin 0 -> 397 bytes .../themes/lighting/bottom-right-darkblue.png | Bin 0 -> 392 bytes .../themes/lighting/bottom-right-green.png | Bin 0 -> 390 bytes .../themes/lighting/bottom-right-grey.png | Bin 0 -> 424 bytes .../themes/lighting/button-close-blue.png | Bin 0 -> 308 bytes .../themes/lighting/button-close-darkblue.png | Bin 0 -> 308 bytes .../themes/lighting/button-close-green.png | Bin 0 -> 305 bytes .../themes/lighting/button-close-grey.png | Bin 0 -> 320 bytes .../themes/lighting/button-maximize-blue.png | Bin 0 -> 218 bytes .../lighting/button-maximize-darkblue.png | Bin 0 -> 212 bytes .../themes/lighting/button-maximize-green.png | Bin 0 -> 226 bytes .../themes/lighting/button-maximize-grey.png | Bin 0 -> 218 bytes .../themes/lighting/button-minimize-blue.png | Bin 0 -> 164 bytes .../lighting/button-minimize-darkblue.png | Bin 0 -> 172 bytes .../themes/lighting/button-minimize-green.png | Bin 0 -> 172 bytes .../themes/lighting/button-minimize-grey.png | Bin 0 -> 184 bytes .../themes/lighting/left-blue.png | Bin 0 -> 144 bytes .../themes/lighting/left-darkblue.png | Bin 0 -> 143 bytes .../themes/lighting/left-green.png | Bin 0 -> 144 bytes .../themes/lighting/left-grey.png | Bin 0 -> 144 bytes .../themes/lighting/pngbehavior.htc | 67 + .../themes/lighting/right-blue.png | Bin 0 -> 146 bytes .../themes/lighting/right-darkblue.png | Bin 0 -> 146 bytes .../themes/lighting/right-green.png | Bin 0 -> 146 bytes .../themes/lighting/right-grey.png | Bin 0 -> 155 bytes .../themes/lighting/spinner.gif | Bin 0 -> 2037 bytes .../themes/lighting/top-left-blue.png | Bin 0 -> 336 bytes .../themes/lighting/top-left-darkblue.png | Bin 0 -> 360 bytes .../themes/lighting/top-left-green.png | Bin 0 -> 339 bytes .../themes/lighting/top-left-grey.png | Bin 0 -> 352 bytes .../themes/lighting/top-middle-blue.png | Bin 0 -> 200 bytes .../themes/lighting/top-middle-darkblue.png | Bin 0 -> 226 bytes .../themes/lighting/top-middle-green.png | Bin 0 -> 208 bytes .../themes/lighting/top-middle-grey.png | Bin 0 -> 185 bytes .../themes/lighting/top-right-blue.png | Bin 0 -> 423 bytes .../themes/lighting/top-right-darkblue.png | Bin 0 -> 451 bytes .../themes/lighting/top-right-green.png | Bin 0 -> 440 bytes .../themes/lighting/top-right-grey.png | Bin 0 -> 495 bytes public/windows_js_1.3/themes/mac_os_x.css | 333 ++ public/windows_js_1.3/themes/mac_os_x/B.png | Bin 0 -> 268 bytes public/windows_js_1.3/themes/mac_os_x/BL.png | Bin 0 -> 5068 bytes .../themes/mac_os_x/BL_Main.png | Bin 0 -> 5068 bytes public/windows_js_1.3/themes/mac_os_x/BR.png | Bin 0 -> 5068 bytes .../themes/mac_os_x/BR_Main.png | Bin 0 -> 5068 bytes .../windows_js_1.3/themes/mac_os_x/B_Main.png | Bin 0 -> 268 bytes public/windows_js_1.3/themes/mac_os_x/L.png | Bin 0 -> 133 bytes .../windows_js_1.3/themes/mac_os_x/L_Main.png | Bin 0 -> 133 bytes public/windows_js_1.3/themes/mac_os_x/R.png | Bin 0 -> 133 bytes .../windows_js_1.3/themes/mac_os_x/R_Main.png | Bin 0 -> 133 bytes public/windows_js_1.3/themes/mac_os_x/T.png | Bin 0 -> 218 bytes public/windows_js_1.3/themes/mac_os_x/TL.png | Bin 0 -> 360 bytes .../themes/mac_os_x/TL_Main.png | Bin 0 -> 444 bytes public/windows_js_1.3/themes/mac_os_x/TR.png | Bin 0 -> 3818 bytes .../themes/mac_os_x/TR_Main.png | Bin 0 -> 3818 bytes .../windows_js_1.3/themes/mac_os_x/T_Main.png | Bin 0 -> 218 bytes .../windows_js_1.3/themes/mac_os_x/close.gif | Bin 0 -> 1012 bytes .../themes/mac_os_x/maximize.gif | Bin 0 -> 1024 bytes .../themes/mac_os_x/minimize.gif | Bin 0 -> 1023 bytes .../windows_js_1.3/themes/mac_os_x_dialog.css | 160 + .../themes/mac_os_x_dialog/B.png | Bin 0 -> 2861 bytes .../themes/mac_os_x_dialog/BL.png | Bin 0 -> 3046 bytes .../themes/mac_os_x_dialog/BR.png | Bin 0 -> 3073 bytes .../themes/mac_os_x_dialog/L.png | Bin 0 -> 133 bytes .../themes/mac_os_x_dialog/R.png | Bin 0 -> 133 bytes .../themes/mac_os_x_dialog/T.png | Bin 0 -> 218 bytes .../themes/mac_os_x_dialog/TL.png | Bin 0 -> 360 bytes .../themes/mac_os_x_dialog/TR.png | Bin 0 -> 3818 bytes .../themes/mac_os_x_dialog/bg.gif | Bin 0 -> 65 bytes .../themes/mac_os_x_dialog/close.gif | Bin 0 -> 1012 bytes .../themes/mac_os_x_dialog/maximize.gif | Bin 0 -> 1024 bytes .../themes/mac_os_x_dialog/minimize.gif | Bin 0 -> 1023 bytes public/windows_js_1.3/themes/nuncio.css | 164 + .../themes/nuncio/bottom_left.png | Bin 0 -> 616 bytes .../themes/nuncio/bottom_mid.png | Bin 0 -> 3617 bytes .../themes/nuncio/bottom_right.png | Bin 0 -> 660 bytes .../themes/nuncio/center_left.png | Bin 0 -> 6606 bytes .../themes/nuncio/center_right.png | Bin 0 -> 6509 bytes public/windows_js_1.3/themes/nuncio/close.png | Bin 0 -> 772 bytes .../windows_js_1.3/themes/nuncio/minimize.png | Bin 0 -> 693 bytes .../windows_js_1.3/themes/nuncio/overlay.png | Bin 0 -> 40803 bytes .../windows_js_1.3/themes/nuncio/top_left.png | Bin 0 -> 971 bytes .../windows_js_1.3/themes/nuncio/top_mid.png | Bin 0 -> 5944 bytes .../themes/nuncio/top_right.png | Bin 0 -> 1245 bytes public/windows_js_1.3/themes/spread.css | 108 + public/windows_js_1.3/themes/spread/.gif | Bin 0 -> 2866 bytes .../themes/spread/bottom-left-c.gif | Bin 0 -> 60 bytes .../themes/spread/bottom-middle.gif | Bin 0 -> 50 bytes .../themes/spread/bottom-right-c.gif | Bin 0 -> 61 bytes .../themes/spread/button-close-focus.gif | Bin 0 -> 699 bytes .../themes/spread/button-max-focus.gif | Bin 0 -> 765 bytes .../themes/spread/button-min-focus.gif | Bin 0 -> 472 bytes .../themes/spread/frame-left.gif | Bin 0 -> 64 bytes .../themes/spread/frame-right.gif | Bin 0 -> 64 bytes .../windows_js_1.3/themes/spread/left-top.gif | Bin 0 -> 273 bytes .../themes/spread/right-top.gif | Bin 0 -> 265 bytes .../themes/spread/top-middle.gif | Bin 0 -> 152 bytes start.bat | 2 + 989 files changed, 118190 insertions(+) create mode 100644 JIRC.js create mode 100644 README create mode 100644 README.txt create mode 100644 lib/IRC.js create mode 100644 lib/entities.js create mode 100644 lib/entities.js.LICENSE create mode 100644 lib/googleweather.js create mode 100644 lib/listdb.js create mode 100644 lib/node-static.js create mode 100644 lib/node-static/mime.js create mode 100644 lib/node-static/util.js create mode 100644 node_modules/.DS_Store create mode 100644 node_modules/growl/History.md create mode 100644 node_modules/growl/Readme.md create mode 100644 node_modules/growl/lib/growl.js create mode 100644 node_modules/growl/package.json create mode 100644 node_modules/growl/test.js create mode 100644 node_modules/jsdom/.npmignore create mode 100644 node_modules/jsdom/LICENSE.txt create mode 100644 node_modules/jsdom/README.md create mode 100644 node_modules/jsdom/benchmark/mark.js create mode 100644 node_modules/jsdom/benchmark/stats.json create mode 100644 node_modules/jsdom/changelog create mode 100644 node_modules/jsdom/example/browser/browser.js create mode 100644 node_modules/jsdom/example/ender/ender.js create mode 100644 node_modules/jsdom/example/ender/run.js create mode 100644 node_modules/jsdom/example/jquery/jquery.js create mode 100644 node_modules/jsdom/example/jquery/run.js create mode 100644 node_modules/jsdom/example/node-xml/example.xml create mode 100644 node_modules/jsdom/example/node-xml/run.js create mode 100644 node_modules/jsdom/example/pure/pure.js create mode 100644 node_modules/jsdom/example/pure/run.js create mode 100644 node_modules/jsdom/example/pure/sax-test.js create mode 100644 node_modules/jsdom/example/pure/sax.js create mode 100644 node_modules/jsdom/example/sizzle/run.js create mode 100644 node_modules/jsdom/example/sizzle/sax.js create mode 100644 node_modules/jsdom/example/sizzle/sizzle.js create mode 100644 node_modules/jsdom/lib/jsdom.js create mode 100644 node_modules/jsdom/lib/jsdom/browser/documentfeatures.js create mode 100644 node_modules/jsdom/lib/jsdom/browser/domtohtml.js create mode 100644 node_modules/jsdom/lib/jsdom/browser/htmlencoding.js create mode 100644 node_modules/jsdom/lib/jsdom/browser/htmltodom.js create mode 100644 node_modules/jsdom/lib/jsdom/browser/index.js create mode 100644 node_modules/jsdom/lib/jsdom/level1/core.js create mode 100644 node_modules/jsdom/lib/jsdom/level2/core.js create mode 100644 node_modules/jsdom/lib/jsdom/level2/events.js create mode 100644 node_modules/jsdom/lib/jsdom/level2/html.js create mode 100644 node_modules/jsdom/lib/jsdom/level2/index.js create mode 100644 node_modules/jsdom/lib/jsdom/level2/languages/javascript.js create mode 100644 node_modules/jsdom/lib/jsdom/level2/style.js create mode 100644 node_modules/jsdom/lib/jsdom/level3/core.js create mode 100644 node_modules/jsdom/lib/jsdom/level3/events.js create mode 100644 node_modules/jsdom/lib/jsdom/level3/html.js create mode 100644 node_modules/jsdom/lib/jsdom/level3/index.js create mode 100644 node_modules/jsdom/lib/jsdom/level3/ls.js create mode 100644 node_modules/jsdom/lib/jsdom/level3/xpath.js create mode 100644 node_modules/jsdom/lib/jsdom/selectors/index.js create mode 100644 node_modules/jsdom/lib/jsdom/selectors/sizzle.js create mode 100644 node_modules/jsdom/lib/jsdom/utils.js create mode 100644 node_modules/jsdom/node_modules/contextify/.npmignore create mode 100644 node_modules/jsdom/node_modules/contextify/LICENSE.txt create mode 100644 node_modules/jsdom/node_modules/contextify/README.md create mode 100644 node_modules/jsdom/node_modules/contextify/binding.gyp create mode 100644 node_modules/jsdom/node_modules/contextify/build/Makefile create mode 100644 node_modules/jsdom/node_modules/contextify/build/Release/.deps/Release/contextify.node.d create mode 100644 node_modules/jsdom/node_modules/contextify/build/Release/.deps/Release/obj.target/contextify/src/contextify.o.d create mode 100644 node_modules/jsdom/node_modules/contextify/build/Release/contextify.node create mode 100644 node_modules/jsdom/node_modules/contextify/build/Release/linker.lock create mode 100644 node_modules/jsdom/node_modules/contextify/build/Release/obj.target/contextify/src/contextify.o create mode 100644 node_modules/jsdom/node_modules/contextify/build/binding.Makefile create mode 100644 node_modules/jsdom/node_modules/contextify/build/config.gypi create mode 100644 node_modules/jsdom/node_modules/contextify/build/contextify.target.mk create mode 100644 node_modules/jsdom/node_modules/contextify/build/gyp-mac-tool create mode 100644 node_modules/jsdom/node_modules/contextify/changelog create mode 100644 node_modules/jsdom/node_modules/contextify/lib/contextify.js create mode 100644 node_modules/jsdom/node_modules/contextify/node_modules/bindings/README.md create mode 100644 node_modules/jsdom/node_modules/contextify/node_modules/bindings/bindings.js create mode 100644 node_modules/jsdom/node_modules/contextify/node_modules/bindings/package.json create mode 100644 node_modules/jsdom/node_modules/contextify/package.json create mode 100644 node_modules/jsdom/node_modules/contextify/src/contextify.cc create mode 100644 node_modules/jsdom/node_modules/contextify/test/contextify.js create mode 100644 node_modules/jsdom/node_modules/contextify/wscript create mode 100644 node_modules/jsdom/node_modules/cssom/.gitmodules create mode 100644 node_modules/jsdom/node_modules/cssom/.npmignore create mode 100644 node_modules/jsdom/node_modules/cssom/README.mdown create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSFontFaceRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSImportRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSKeyframeRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSKeyframesRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSMediaRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSStyleDeclaration.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSStyleRule.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/CSSStyleSheet.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/MediaList.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/StyleSheet.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/clone.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/index.js create mode 100644 node_modules/jsdom/node_modules/cssom/lib/parse.js create mode 100644 node_modules/jsdom/node_modules/cssom/package.json create mode 100644 node_modules/jsdom/node_modules/htmlparser/.project create mode 100644 node_modules/jsdom/node_modules/htmlparser/.project.bak create mode 100644 node_modules/jsdom/node_modules/htmlparser/.settings/.jsdtscope create mode 100644 node_modules/jsdom/node_modules/htmlparser/.settings/org.eclipse.core.resources.prefs create mode 100644 node_modules/jsdom/node_modules/htmlparser/.settings/org.eclipse.wst.jsdt.ui.superType.container create mode 100644 node_modules/jsdom/node_modules/htmlparser/.settings/org.eclipse.wst.jsdt.ui.superType.name create mode 100644 node_modules/jsdom/node_modules/htmlparser/CHANGELOG create mode 100644 node_modules/jsdom/node_modules/htmlparser/LICENSE create mode 100644 node_modules/jsdom/node_modules/htmlparser/README.md create mode 100644 node_modules/jsdom/node_modules/htmlparser/a create mode 100644 node_modules/jsdom/node_modules/htmlparser/b create mode 100644 node_modules/jsdom/node_modules/htmlparser/c create mode 100644 node_modules/jsdom/node_modules/htmlparser/json2.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/lib/htmlparser.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/lib/htmlparser.min.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.min.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/libxmljs.node create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/a create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/b create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/compat.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/htmlparser.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/parser.zip create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/test01.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/new/test02.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/newparser.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/node-htmlparser.old.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/package.json create mode 100644 node_modules/jsdom/node_modules/htmlparser/profile create mode 100644 node_modules/jsdom/node_modules/htmlparser/profile.getelement.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/profile.getelement.txt create mode 100644 node_modules/jsdom/node_modules/htmlparser/profile.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/profileresults.txt create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/CHANGELOG create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/LICENSE create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/README.md create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/json2.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/lib/node-htmlparser.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/lib/node-htmlparser.min.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/package.json create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/profile.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/snippet.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/01-basic.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/02-single_tag_1.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/03-single_tag_2.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/04-unescaped_in_script.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/05-tags_in_comment.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/06-comment_in_script.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/07-unescaped_in_style.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/08-extra_spaces_in_tag.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/09-unquoted_attrib.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/10-singular_attribute.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/11-text_outside_tags.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/12-text_only.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/13-comment_in_text.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/14-comment_in_text_in_script.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/15-non-verbose.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/16-ignore_whitespace.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/17-xml_namespace.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/18-enforce_empty_tags.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/19-ignore_empty_tags.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/20-rss.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/21-atom.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/utils_example.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/rssbug.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/rssbug.rss create mode 100644 node_modules/jsdom/node_modules/htmlparser/runtests.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/runtests.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/runtests.min.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/runtests.min.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/runtests_new.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/snippet.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/test01.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_test.html.2854~ create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.65425~ create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.76922~ create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.80022~ create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.51378~ create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.75287~ create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/api.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/getelement.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/testdata/trackerchecker.html create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/01-basic.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/02-single_tag_1.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/03-single_tag_2.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/04-unescaped_in_script.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/05-tags_in_comment.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/06-comment_in_script.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/07-unescaped_in_style.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/08-extra_spaces_in_tag.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/09-unquoted_attrib.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/10-singular_attribute.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/11-text_outside_tags.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/12-text_only.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/13-comment_in_text.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/14-comment_in_text_in_script.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/15-non-verbose.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/16-ignore_whitespace.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/17-xml_namespace.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/18-enforce_empty_tags.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/19-ignore_empty_tags.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/20-rss.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/21-atom.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tests/22-position_data.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/tmp/snippet.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/utils_example.js create mode 100644 node_modules/jsdom/node_modules/htmlparser/v8.log create mode 100644 node_modules/jsdom/package.json create mode 100644 node_modules/jsdom/status.json create mode 100644 node_modules/mime/LICENSE create mode 100644 node_modules/mime/README.md create mode 100644 node_modules/mime/mime.js create mode 100644 node_modules/mime/package.json create mode 100644 node_modules/mime/test.js create mode 100644 node_modules/mime/types/mime.types create mode 100644 node_modules/mime/types/node.types create mode 100644 node_modules/node-static/.DS_Store create mode 100644 node_modules/node-static/lib/node-static.js create mode 100644 node_modules/node-static/lib/node-static/mime.js create mode 100644 node_modules/node-static/lib/node-static/util.js create mode 100644 node_modules/node-static/package.json create mode 100644 node_modules/openurl/.npmignore create mode 100644 node_modules/openurl/README.md create mode 100644 node_modules/openurl/openurl.js create mode 100644 node_modules/openurl/package.json create mode 100644 node_modules/optimist/.travis.yml create mode 100644 node_modules/optimist/LICENSE create mode 100644 node_modules/optimist/README.markdown create mode 100644 node_modules/optimist/example/bool.js create mode 100644 node_modules/optimist/example/boolean_double.js create mode 100644 node_modules/optimist/example/boolean_single.js create mode 100644 node_modules/optimist/example/default_hash.js create mode 100644 node_modules/optimist/example/default_singles.js create mode 100644 node_modules/optimist/example/divide.js create mode 100644 node_modules/optimist/example/line_count.js create mode 100644 node_modules/optimist/example/line_count_options.js create mode 100644 node_modules/optimist/example/line_count_wrap.js create mode 100644 node_modules/optimist/example/nonopt.js create mode 100644 node_modules/optimist/example/reflect.js create mode 100644 node_modules/optimist/example/short.js create mode 100644 node_modules/optimist/example/string.js create mode 100644 node_modules/optimist/example/usage-options.js create mode 100644 node_modules/optimist/example/xup.js create mode 100644 node_modules/optimist/index.js create mode 100644 node_modules/optimist/node_modules/wordwrap/.npmignore create mode 100644 node_modules/optimist/node_modules/wordwrap/README.markdown create mode 100644 node_modules/optimist/node_modules/wordwrap/example/center.js create mode 100644 node_modules/optimist/node_modules/wordwrap/example/meat.js create mode 100644 node_modules/optimist/node_modules/wordwrap/index.js create mode 100644 node_modules/optimist/node_modules/wordwrap/package.json create mode 100644 node_modules/optimist/node_modules/wordwrap/test/break.js create mode 100644 node_modules/optimist/node_modules/wordwrap/test/idleness.txt create mode 100644 node_modules/optimist/node_modules/wordwrap/test/wrap.js create mode 100644 node_modules/optimist/package.json create mode 100644 node_modules/optimist/test/_.js create mode 100644 node_modules/optimist/test/_/argv.js create mode 100644 node_modules/optimist/test/_/bin.js create mode 100644 node_modules/optimist/test/parse.js create mode 100644 node_modules/optimist/test/usage.js create mode 100644 node_modules/optimist/x.js create mode 100644 node_modules/request/LICENSE create mode 100644 node_modules/request/README.md create mode 100644 node_modules/request/aws.js create mode 100644 node_modules/request/forever.js create mode 100644 node_modules/request/main.js create mode 100644 node_modules/request/node_modules/form-data/.npmignore create mode 100644 node_modules/request/node_modules/form-data/Makefile create mode 100644 node_modules/request/node_modules/form-data/Readme.md create mode 100644 node_modules/request/node_modules/form-data/lib/form_data.js create mode 100644 node_modules/request/node_modules/form-data/node-form-data.sublime-project create mode 100644 node_modules/request/node_modules/form-data/node-form-data.sublime-workspace create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/.gitmodules create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/LICENSE create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/Makefile create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/README.md create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/index.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/lib/async.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/nodelint.cfg create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/package.json create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/test/.swp create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/async/test/test.html create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/License create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js create mode 100644 node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js create mode 100644 node_modules/request/node_modules/form-data/package.json create mode 100644 node_modules/request/node_modules/form-data/test/common.js create mode 100644 node_modules/request/node_modules/form-data/test/fixture/bacon.txt create mode 100644 node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg create mode 100644 node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js create mode 100644 node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js create mode 100644 node_modules/request/node_modules/form-data/test/integration/test-http-response.js create mode 100644 node_modules/request/node_modules/form-data/test/integration/test-pipe.js create mode 100644 node_modules/request/node_modules/form-data/test/integration/test-submit.js create mode 100644 node_modules/request/node_modules/form-data/test/run.js create mode 100644 node_modules/request/node_modules/mime/LICENSE create mode 100644 node_modules/request/node_modules/mime/README.md create mode 100644 node_modules/request/node_modules/mime/mime.js create mode 100644 node_modules/request/node_modules/mime/package.json create mode 100644 node_modules/request/node_modules/mime/test.js create mode 100644 node_modules/request/node_modules/mime/types/mime.types create mode 100644 node_modules/request/node_modules/mime/types/node.types create mode 100644 node_modules/request/oauth.js create mode 100644 node_modules/request/package.json create mode 100644 node_modules/request/tests/googledoodle.png create mode 100644 node_modules/request/tests/run.js create mode 100644 node_modules/request/tests/server.js create mode 100644 node_modules/request/tests/squid.conf create mode 100644 node_modules/request/tests/ssl/ca/ca.cnf create mode 100644 node_modules/request/tests/ssl/ca/ca.crl create mode 100644 node_modules/request/tests/ssl/ca/ca.crt create mode 100644 node_modules/request/tests/ssl/ca/ca.csr create mode 100644 node_modules/request/tests/ssl/ca/ca.key create mode 100644 node_modules/request/tests/ssl/ca/ca.srl create mode 100644 node_modules/request/tests/ssl/ca/server.cnf create mode 100644 node_modules/request/tests/ssl/ca/server.crt create mode 100644 node_modules/request/tests/ssl/ca/server.csr create mode 100644 node_modules/request/tests/ssl/ca/server.js create mode 100644 node_modules/request/tests/ssl/ca/server.key create mode 100644 node_modules/request/tests/ssl/npm-ca.crt create mode 100644 node_modules/request/tests/ssl/test.crt create mode 100644 node_modules/request/tests/ssl/test.key create mode 100644 node_modules/request/tests/test-body.js create mode 100644 node_modules/request/tests/test-cookie.js create mode 100644 node_modules/request/tests/test-cookiejar.js create mode 100644 node_modules/request/tests/test-defaults.js create mode 100644 node_modules/request/tests/test-errors.js create mode 100644 node_modules/request/tests/test-follow-all-303.js create mode 100644 node_modules/request/tests/test-follow-all.js create mode 100644 node_modules/request/tests/test-form.js create mode 100644 node_modules/request/tests/test-headers.js create mode 100644 node_modules/request/tests/test-httpModule.js create mode 100644 node_modules/request/tests/test-https-strict.js create mode 100644 node_modules/request/tests/test-https.js create mode 100644 node_modules/request/tests/test-oauth.js create mode 100644 node_modules/request/tests/test-params.js create mode 100644 node_modules/request/tests/test-piped-redirect.js create mode 100644 node_modules/request/tests/test-pipes.js create mode 100644 node_modules/request/tests/test-pool.js create mode 100644 node_modules/request/tests/test-protocol-changing-redirect.js create mode 100644 node_modules/request/tests/test-proxy.js create mode 100644 node_modules/request/tests/test-qs.js create mode 100644 node_modules/request/tests/test-redirect.js create mode 100644 node_modules/request/tests/test-s3.js create mode 100644 node_modules/request/tests/test-timeout.js create mode 100644 node_modules/request/tests/test-toJSON.js create mode 100644 node_modules/request/tests/test-tunnel.js create mode 100644 node_modules/request/tests/unicycle.jpg create mode 100644 node_modules/request/tunnel.js create mode 100644 node_modules/request/uuid.js create mode 100644 node_modules/request/vendor/cookie/index.js create mode 100644 node_modules/request/vendor/cookie/jar.js create mode 100644 node_modules/underscore/.npmignore create mode 100644 node_modules/underscore/CNAME create mode 100644 node_modules/underscore/CONTRIBUTING.md create mode 100644 node_modules/underscore/LICENSE create mode 100644 node_modules/underscore/README.md create mode 100644 node_modules/underscore/favicon.ico create mode 100644 node_modules/underscore/index.html create mode 100644 node_modules/underscore/index.js create mode 100644 node_modules/underscore/package.json create mode 100644 node_modules/underscore/raw/underscore.psd create mode 100644 node_modules/underscore/underscore-min.js create mode 100644 node_modules/underscore/underscore.js create mode 100644 node_modules/websocket-server/.npmignore create mode 100644 node_modules/websocket-server/LICENSE.md create mode 100644 node_modules/websocket-server/Makefile create mode 100644 node_modules/websocket-server/README.md create mode 100644 node_modules/websocket-server/docs/index.html create mode 100644 node_modules/websocket-server/docs/style.css create mode 100644 node_modules/websocket-server/lib/_events.js create mode 100644 node_modules/websocket-server/lib/_util.js create mode 100644 node_modules/websocket-server/lib/lang/mixin.js create mode 100644 node_modules/websocket-server/lib/ws/connection.js create mode 100644 node_modules/websocket-server/lib/ws/manager.js create mode 100644 node_modules/websocket-server/lib/ws/parser.js create mode 100644 node_modules/websocket-server/lib/ws/server.js create mode 100644 node_modules/websocket-server/package.json create mode 100644 node_modules/websocket-server/samples/handshake-packets create mode 100644 node_modules/websocket-server/test/common.js create mode 100644 node_modules/websocket-server/test/fixtures/.npmignore create mode 100644 node_modules/websocket-server/test/manual/chat-server.js create mode 100644 node_modules/websocket-server/test/manual/chat.html create mode 100644 node_modules/websocket-server/test/manual/client.html create mode 100644 node_modules/websocket-server/test/manual/dev-server.js create mode 100644 node_modules/websocket-server/test/manual/echo-server.js create mode 100644 node_modules/websocket-server/test/manual/ssl/cert.key create mode 100644 node_modules/websocket-server/test/manual/ssl/cert.pem create mode 100644 node_modules/websocket-server/test/manual/test-https-upgrade.js create mode 100644 node_modules/websocket-server/test/pummel/.npmignore create mode 100644 node_modules/websocket-server/test/simple/.npmignore create mode 100644 node_modules/websocket-server/tools/release.js create mode 100644 node_modules/websocket/CHANGELOG.md create mode 100644 node_modules/websocket/LICENSE create mode 100644 node_modules/websocket/Makefile create mode 100644 node_modules/websocket/README.md create mode 100644 node_modules/websocket/binding.gyp create mode 100644 node_modules/websocket/build/Makefile create mode 100644 node_modules/websocket/build/Release/.deps/Release/obj.target/validation/src/validation.o.d create mode 100644 node_modules/websocket/build/Release/.deps/Release/obj.target/xor/src/xor.o.d create mode 100644 node_modules/websocket/build/Release/.deps/Release/validation.node.d create mode 100644 node_modules/websocket/build/Release/.deps/Release/xor.node.d create mode 100644 node_modules/websocket/build/Release/linker.lock create mode 100644 node_modules/websocket/build/Release/obj.target/validation/src/validation.o create mode 100644 node_modules/websocket/build/Release/obj.target/xor/src/xor.o create mode 100644 node_modules/websocket/build/Release/validation.node create mode 100644 node_modules/websocket/build/Release/xor.node create mode 100644 node_modules/websocket/build/binding.Makefile create mode 100644 node_modules/websocket/build/config.gypi create mode 100644 node_modules/websocket/build/gyp-mac-tool create mode 100644 node_modules/websocket/build/validation.target.mk create mode 100644 node_modules/websocket/build/xor.target.mk create mode 100644 node_modules/websocket/index.js create mode 100644 node_modules/websocket/install.js create mode 100644 node_modules/websocket/lib/Constants.js create mode 100644 node_modules/websocket/lib/Validation.fallback.js create mode 100644 node_modules/websocket/lib/Validation.js create mode 100644 node_modules/websocket/lib/WebSocketClient.js create mode 100644 node_modules/websocket/lib/WebSocketConnection.js create mode 100644 node_modules/websocket/lib/WebSocketFrame.js create mode 100644 node_modules/websocket/lib/WebSocketRequest.js create mode 100644 node_modules/websocket/lib/WebSocketRouter.js create mode 100644 node_modules/websocket/lib/WebSocketRouterRequest.js create mode 100644 node_modules/websocket/lib/WebSocketServer.js create mode 100644 node_modules/websocket/lib/utils.js create mode 100644 node_modules/websocket/lib/websocket.js create mode 100644 node_modules/websocket/lib/xor.fallback.js create mode 100644 node_modules/websocket/lib/xor.js create mode 100644 node_modules/websocket/package.json create mode 100644 node_modules/websocket/src/validation.cc create mode 100644 node_modules/websocket/src/xor.cpp create mode 100644 node_modules/websocket/vendor/FastBufferList.js create mode 100644 node_modules/websocket/vendor/node-ctype/LICENSE create mode 100644 node_modules/websocket/vendor/node-ctype/ctio-faster.js create mode 100644 public/.DS_Store create mode 100644 public/body-bg.png create mode 100644 public/body-bg2.jpg create mode 100644 public/button-bg.gif create mode 100644 public/classes.js create mode 100644 public/date.format.js create mode 100644 public/dock-bg.gif create mode 100644 public/emoticons.xml create mode 100644 public/fonts/PT Mono SIL OFL Font License 1.1.txt create mode 100644 public/fonts/PTM55FT-webfont.eot create mode 100644 public/fonts/PTM55FT-webfont.svg create mode 100644 public/fonts/PTM55FT-webfont.ttf create mode 100644 public/fonts/PTM55FT-webfont.woff create mode 100644 public/fonts/demo.html create mode 100644 public/fonts/pt-mono-fontfacekit.zip create mode 100644 public/fonts/stylesheet.css create mode 100644 public/images/.DS_Store create mode 100644 public/images/emoticons/1.gif create mode 100644 public/images/emoticons/10.gif create mode 100644 public/images/emoticons/100.gif create mode 100644 public/images/emoticons/101.gif create mode 100644 public/images/emoticons/102.gif create mode 100644 public/images/emoticons/103.gif create mode 100644 public/images/emoticons/104.gif create mode 100644 public/images/emoticons/105.gif create mode 100644 public/images/emoticons/106.gif create mode 100644 public/images/emoticons/107.gif create mode 100644 public/images/emoticons/108.gif create mode 100644 public/images/emoticons/109.gif create mode 100644 public/images/emoticons/11.gif create mode 100644 public/images/emoticons/110.gif create mode 100644 public/images/emoticons/111.gif create mode 100644 public/images/emoticons/112.gif create mode 100644 public/images/emoticons/113.gif create mode 100644 public/images/emoticons/114.gif create mode 100644 public/images/emoticons/115.gif create mode 100644 public/images/emoticons/12.gif create mode 100644 public/images/emoticons/13.gif create mode 100644 public/images/emoticons/14.gif create mode 100644 public/images/emoticons/15.gif create mode 100644 public/images/emoticons/16.gif create mode 100644 public/images/emoticons/17.gif create mode 100644 public/images/emoticons/18.gif create mode 100644 public/images/emoticons/19.gif create mode 100644 public/images/emoticons/2.gif create mode 100644 public/images/emoticons/20.gif create mode 100644 public/images/emoticons/21.gif create mode 100644 public/images/emoticons/22.gif create mode 100644 public/images/emoticons/23.gif create mode 100644 public/images/emoticons/24.gif create mode 100644 public/images/emoticons/25.gif create mode 100644 public/images/emoticons/26.gif create mode 100644 public/images/emoticons/27.gif create mode 100644 public/images/emoticons/28.gif create mode 100644 public/images/emoticons/29.gif create mode 100644 public/images/emoticons/3.gif create mode 100644 public/images/emoticons/30.gif create mode 100644 public/images/emoticons/31.gif create mode 100644 public/images/emoticons/32.gif create mode 100644 public/images/emoticons/33.gif create mode 100644 public/images/emoticons/34.gif create mode 100644 public/images/emoticons/35.gif create mode 100644 public/images/emoticons/36.gif create mode 100644 public/images/emoticons/37.gif create mode 100644 public/images/emoticons/38.gif create mode 100644 public/images/emoticons/39.gif create mode 100644 public/images/emoticons/4.gif create mode 100644 public/images/emoticons/40.gif create mode 100644 public/images/emoticons/41.gif create mode 100644 public/images/emoticons/42.gif create mode 100644 public/images/emoticons/43.gif create mode 100644 public/images/emoticons/44.gif create mode 100644 public/images/emoticons/45.gif create mode 100644 public/images/emoticons/46.gif create mode 100644 public/images/emoticons/47.gif create mode 100644 public/images/emoticons/48.gif create mode 100644 public/images/emoticons/49.gif create mode 100644 public/images/emoticons/5.gif create mode 100644 public/images/emoticons/50.gif create mode 100644 public/images/emoticons/51.gif create mode 100644 public/images/emoticons/52.gif create mode 100644 public/images/emoticons/53.gif create mode 100644 public/images/emoticons/54.gif create mode 100644 public/images/emoticons/55.gif create mode 100644 public/images/emoticons/56.gif create mode 100644 public/images/emoticons/57.gif create mode 100644 public/images/emoticons/58.gif create mode 100644 public/images/emoticons/59.gif create mode 100644 public/images/emoticons/6.gif create mode 100644 public/images/emoticons/60.gif create mode 100644 public/images/emoticons/61.gif create mode 100644 public/images/emoticons/62.gif create mode 100644 public/images/emoticons/63.gif create mode 100644 public/images/emoticons/64.gif create mode 100644 public/images/emoticons/65.gif create mode 100644 public/images/emoticons/66.gif create mode 100644 public/images/emoticons/67.gif create mode 100644 public/images/emoticons/68.gif create mode 100644 public/images/emoticons/69.gif create mode 100644 public/images/emoticons/7.gif create mode 100644 public/images/emoticons/70.gif create mode 100644 public/images/emoticons/71.gif create mode 100644 public/images/emoticons/72.gif create mode 100644 public/images/emoticons/73.gif create mode 100644 public/images/emoticons/74.gif create mode 100644 public/images/emoticons/75.gif create mode 100644 public/images/emoticons/76.gif create mode 100644 public/images/emoticons/77.gif create mode 100644 public/images/emoticons/78.gif create mode 100644 public/images/emoticons/79.gif create mode 100644 public/images/emoticons/8.gif create mode 100644 public/images/emoticons/9.gif create mode 100644 public/images/emoticons/Emoticons.plist create mode 100644 public/images/emoticons/pirate.gif create mode 100644 public/images/emoticons/test.txt create mode 100644 public/images/emoticons/transformer.gif create mode 100644 public/images/ew.gif create mode 100644 public/images/resize.gif create mode 100644 public/index.html create mode 100644 public/main.css create mode 100644 public/main.js create mode 100644 public/plist_parser.js create mode 100644 public/pwc-os.js create mode 100644 public/resize.gif create mode 100644 public/server.js create mode 100644 public/windows_js_1.3/MIT-LICENSE create mode 100644 public/windows_js_1.3/PWC-OS/body-bg.png create mode 100644 public/windows_js_1.3/PWC-OS/button-bg.gif create mode 100644 public/windows_js_1.3/PWC-OS/dock-bg.gif create mode 100644 public/windows_js_1.3/PWC-OS/index.html create mode 100644 public/windows_js_1.3/PWC-OS/pwc-os.css create mode 100644 public/windows_js_1.3/PWC-OS/pwc-os.js create mode 100644 public/windows_js_1.3/README create mode 100644 public/windows_js_1.3/documentation/PWC-OS/body-bg.png create mode 100644 public/windows_js_1.3/documentation/PWC-OS/button-bg.gif create mode 100644 public/windows_js_1.3/documentation/PWC-OS/dock-bg.gif create mode 100644 public/windows_js_1.3/documentation/PWC-OS/index.html create mode 100644 public/windows_js_1.3/documentation/PWC-OS/pwc-os.css create mode 100644 public/windows_js_1.3/documentation/PWC-OS/pwc-os.js create mode 100644 public/windows_js_1.3/documentation/debug.html create mode 100644 public/windows_js_1.3/documentation/documentation.html create mode 100644 public/windows_js_1.3/documentation/info_panel.html create mode 100644 public/windows_js_1.3/documentation/javascripts/debug.js create mode 100644 public/windows_js_1.3/documentation/javascripts/effects.js create mode 100644 public/windows_js_1.3/documentation/javascripts/extended_debug.js create mode 100644 public/windows_js_1.3/documentation/javascripts/prototype.js create mode 100644 public/windows_js_1.3/documentation/javascripts/tooltip.js create mode 100644 public/windows_js_1.3/documentation/javascripts/window.js create mode 100644 public/windows_js_1.3/documentation/javascripts/window_effects.js create mode 100644 public/windows_js_1.3/documentation/javascripts/window_ext.js create mode 100644 public/windows_js_1.3/documentation/js/application.js create mode 100644 public/windows_js_1.3/documentation/logo.gif create mode 100644 public/windows_js_1.3/documentation/pwc.gif create mode 100644 public/windows_js_1.3/documentation/pwc_os_thumb.png create mode 100644 public/windows_js_1.3/documentation/samples.html create mode 100644 public/windows_js_1.3/documentation/stylesheets/login.css create mode 100644 public/windows_js_1.3/documentation/stylesheets/style.css create mode 100644 public/windows_js_1.3/documentation/themes.html create mode 100644 public/windows_js_1.3/documentation/themes/alert.css create mode 100644 public/windows_js_1.3/documentation/themes/alert/bottom.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/bottom_left.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/bottom_right.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/left.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/overlay.png create mode 100644 public/windows_js_1.3/documentation/themes/alert/progress.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/right.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/top.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/top_left.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert/top_right.gif create mode 100644 public/windows_js_1.3/documentation/themes/alert_lite.css create mode 100644 public/windows_js_1.3/documentation/themes/alphacube.css create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/bottom-left-c.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/bottom-middle.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/bottom-right-c.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/button-close-focus.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/button-max-focus.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/button-min-focus.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/frame-left.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/frame-right.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/left-top.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/right-top.gif create mode 100644 public/windows_js_1.3/documentation/themes/alphacube/top-middle.gif create mode 100644 public/windows_js_1.3/documentation/themes/behavior.htc create mode 100644 public/windows_js_1.3/documentation/themes/darkX.css create mode 100644 public/windows_js_1.3/documentation/themes/darkX/button-close-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/button-maximize-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/button-minimize-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/frame-bottom-left-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/frame-bottom-mid-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/frame-bottom-right-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/frame-left-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/frame-right-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/titlebar-left-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/titlebar-mid-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/darkX/titlebar-right-focused.png create mode 100644 public/windows_js_1.3/documentation/themes/debug.css create mode 100644 public/windows_js_1.3/documentation/themes/default.css create mode 100644 public/windows_js_1.3/documentation/themes/default/bottom_left.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/bottom_mid.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/bottom_right.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/bottom_right_resize.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/center_left.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/center_right.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/clear.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/close.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/inspect.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/maximize.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/minimize.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/overlay.png create mode 100644 public/windows_js_1.3/documentation/themes/default/resize.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/sizer.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/top_left.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/top_mid.gif create mode 100644 public/windows_js_1.3/documentation/themes/default/top_right.gif create mode 100644 public/windows_js_1.3/documentation/themes/iefix/blank.gif create mode 100644 public/windows_js_1.3/documentation/themes/iefix/iepngfix.css create mode 100644 public/windows_js_1.3/documentation/themes/iefix/iepngfix.htc create mode 100644 public/windows_js_1.3/documentation/themes/lighting.css create mode 100644 public/windows_js_1.3/documentation/themes/lighting/background_buttons.gif create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-left-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-left-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-left-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-left-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-middle-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-middle-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-middle-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-middle-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-right-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-right-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-right-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/bottom-right-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-close-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-close-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-close-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-close-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-maximize-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-maximize-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-maximize-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-maximize-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-minimize-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-minimize-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-minimize-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/button-minimize-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/left-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/left-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/left-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/left-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/pngbehavior.htc create mode 100644 public/windows_js_1.3/documentation/themes/lighting/right-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/right-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/right-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/right-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/spinner.gif create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-left-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-left-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-left-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-left-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-middle-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-middle-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-middle-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-middle-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-right-blue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-right-darkblue.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-right-green.png create mode 100644 public/windows_js_1.3/documentation/themes/lighting/top-right-grey.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x.css create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/B.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/BL.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/BL_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/BR.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/BR_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/B_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/L.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/L_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/R.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/R_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/T.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/TL.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/TL_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/TR.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/TR_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/T_Main.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/close.gif create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/maximize.gif create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x/minimize.gif create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog.css create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/B.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/BL.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/BR.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/L.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/R.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/T.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/TL.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/TR.png create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/bg.gif create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/close.gif create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/maximize.gif create mode 100644 public/windows_js_1.3/documentation/themes/mac_os_x_dialog/minimize.gif create mode 100644 public/windows_js_1.3/documentation/themes/nuncio.css create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/bottom_left.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/bottom_mid.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/bottom_right.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/center_left.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/center_right.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/close.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/minimize.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/overlay.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/top_left.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/top_mid.png create mode 100644 public/windows_js_1.3/documentation/themes/nuncio/top_right.png create mode 100644 public/windows_js_1.3/documentation/themes/spread.css create mode 100644 public/windows_js_1.3/documentation/themes/spread/.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/bottom-left-c.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/bottom-middle.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/bottom-right-c.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/button-close-focus.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/button-max-focus.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/button-min-focus.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/frame-left.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/frame-right.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/left-top.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/right-top.gif create mode 100644 public/windows_js_1.3/documentation/themes/spread/top-middle.gif create mode 100644 public/windows_js_1.3/helper/prototype_window_class_helper.rb create mode 100644 public/windows_js_1.3/javascripts/debug.js create mode 100644 public/windows_js_1.3/javascripts/effects.js create mode 100644 public/windows_js_1.3/javascripts/extended_debug.js create mode 100644 public/windows_js_1.3/javascripts/prototype.js create mode 100644 public/windows_js_1.3/javascripts/tooltip.js create mode 100644 public/windows_js_1.3/javascripts/window.js create mode 100644 public/windows_js_1.3/javascripts/window_effects.js create mode 100644 public/windows_js_1.3/javascripts/window_ext.js create mode 100644 public/windows_js_1.3/samples/constraint.html create mode 100644 public/windows_js_1.3/samples/dialog.html create mode 100644 public/windows_js_1.3/samples/dialog_ajax.html create mode 100644 public/windows_js_1.3/samples/inframe.html create mode 100644 public/windows_js_1.3/samples/inset.html create mode 100644 public/windows_js_1.3/samples/multi_modal.html create mode 100644 public/windows_js_1.3/samples/oldFirstSampleCode.html create mode 100644 public/windows_js_1.3/samples/openInside.html create mode 100644 public/windows_js_1.3/samples/parent.html create mode 100644 public/windows_js_1.3/samples/popup_open.html create mode 100644 public/windows_js_1.3/samples/rico/index.html create mode 100644 public/windows_js_1.3/samples/rico/properties_1.gif create mode 100644 public/windows_js_1.3/samples/rico/rico.css create mode 100644 public/windows_js_1.3/samples/rico/rico_change.js create mode 100644 public/windows_js_1.3/samples/tooltips/tooltip.html create mode 100644 public/windows_js_1.3/samples/tooltips/tooltip_ajax.html create mode 100644 public/windows_js_1.3/samples/tooltips/tooltip_url.html create mode 100644 public/windows_js_1.3/samples/window_key.html create mode 100644 public/windows_js_1.3/samples/window_key_url_content.html create mode 100644 public/windows_js_1.3/samples/window_store.html create mode 100644 public/windows_js_1.3/themes/alert.css create mode 100644 public/windows_js_1.3/themes/alert/bottom.gif create mode 100644 public/windows_js_1.3/themes/alert/bottom_left.gif create mode 100644 public/windows_js_1.3/themes/alert/bottom_right.gif create mode 100644 public/windows_js_1.3/themes/alert/left.gif create mode 100644 public/windows_js_1.3/themes/alert/overlay.png create mode 100644 public/windows_js_1.3/themes/alert/progress.gif create mode 100644 public/windows_js_1.3/themes/alert/right.gif create mode 100644 public/windows_js_1.3/themes/alert/top.gif create mode 100644 public/windows_js_1.3/themes/alert/top_left.gif create mode 100644 public/windows_js_1.3/themes/alert/top_right.gif create mode 100644 public/windows_js_1.3/themes/alert_lite.css create mode 100644 public/windows_js_1.3/themes/alphacube.css create mode 100644 public/windows_js_1.3/themes/alphacube/bottom-left-c.gif create mode 100644 public/windows_js_1.3/themes/alphacube/bottom-middle.gif create mode 100644 public/windows_js_1.3/themes/alphacube/bottom-right-c.gif create mode 100644 public/windows_js_1.3/themes/alphacube/button-close-focus.gif create mode 100644 public/windows_js_1.3/themes/alphacube/button-max-focus.gif create mode 100644 public/windows_js_1.3/themes/alphacube/button-min-focus.gif create mode 100644 public/windows_js_1.3/themes/alphacube/frame-left.gif create mode 100644 public/windows_js_1.3/themes/alphacube/frame-right.gif create mode 100644 public/windows_js_1.3/themes/alphacube/left-top.gif create mode 100644 public/windows_js_1.3/themes/alphacube/right-top.gif create mode 100644 public/windows_js_1.3/themes/alphacube/top-middle.gif create mode 100644 public/windows_js_1.3/themes/behavior.htc create mode 100644 public/windows_js_1.3/themes/darkX.css create mode 100644 public/windows_js_1.3/themes/darkX/button-close-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/button-maximize-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/button-minimize-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/frame-bottom-left-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/frame-bottom-mid-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/frame-bottom-right-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/frame-left-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/frame-right-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/titlebar-left-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/titlebar-mid-focused.png create mode 100644 public/windows_js_1.3/themes/darkX/titlebar-right-focused.png create mode 100644 public/windows_js_1.3/themes/debug.css create mode 100644 public/windows_js_1.3/themes/default.css create mode 100644 public/windows_js_1.3/themes/default/bottom_left.gif create mode 100644 public/windows_js_1.3/themes/default/bottom_mid.gif create mode 100644 public/windows_js_1.3/themes/default/bottom_right.gif create mode 100644 public/windows_js_1.3/themes/default/bottom_right_resize.gif create mode 100644 public/windows_js_1.3/themes/default/center_left.gif create mode 100644 public/windows_js_1.3/themes/default/center_right.gif create mode 100644 public/windows_js_1.3/themes/default/clear.gif create mode 100644 public/windows_js_1.3/themes/default/close.gif create mode 100644 public/windows_js_1.3/themes/default/inspect.gif create mode 100644 public/windows_js_1.3/themes/default/maximize.gif create mode 100644 public/windows_js_1.3/themes/default/minimize.gif create mode 100644 public/windows_js_1.3/themes/default/overlay.png create mode 100644 public/windows_js_1.3/themes/default/resize.gif create mode 100644 public/windows_js_1.3/themes/default/sizer.gif create mode 100644 public/windows_js_1.3/themes/default/top_left.gif create mode 100644 public/windows_js_1.3/themes/default/top_mid.gif create mode 100644 public/windows_js_1.3/themes/default/top_right.gif create mode 100644 public/windows_js_1.3/themes/iefix/blank.gif create mode 100644 public/windows_js_1.3/themes/iefix/iepngfix.css create mode 100644 public/windows_js_1.3/themes/iefix/iepngfix.htc create mode 100644 public/windows_js_1.3/themes/lighting.css create mode 100644 public/windows_js_1.3/themes/lighting/background_buttons.gif create mode 100644 public/windows_js_1.3/themes/lighting/bottom-left-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-left-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-left-green.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-left-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-middle-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-middle-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-middle-green.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-middle-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-right-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-right-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-right-green.png create mode 100644 public/windows_js_1.3/themes/lighting/bottom-right-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/button-close-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/button-close-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/button-close-green.png create mode 100644 public/windows_js_1.3/themes/lighting/button-close-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/button-maximize-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/button-maximize-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/button-maximize-green.png create mode 100644 public/windows_js_1.3/themes/lighting/button-maximize-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/button-minimize-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/button-minimize-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/button-minimize-green.png create mode 100644 public/windows_js_1.3/themes/lighting/button-minimize-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/left-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/left-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/left-green.png create mode 100644 public/windows_js_1.3/themes/lighting/left-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/pngbehavior.htc create mode 100644 public/windows_js_1.3/themes/lighting/right-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/right-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/right-green.png create mode 100644 public/windows_js_1.3/themes/lighting/right-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/spinner.gif create mode 100644 public/windows_js_1.3/themes/lighting/top-left-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/top-left-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/top-left-green.png create mode 100644 public/windows_js_1.3/themes/lighting/top-left-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/top-middle-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/top-middle-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/top-middle-green.png create mode 100644 public/windows_js_1.3/themes/lighting/top-middle-grey.png create mode 100644 public/windows_js_1.3/themes/lighting/top-right-blue.png create mode 100644 public/windows_js_1.3/themes/lighting/top-right-darkblue.png create mode 100644 public/windows_js_1.3/themes/lighting/top-right-green.png create mode 100644 public/windows_js_1.3/themes/lighting/top-right-grey.png create mode 100644 public/windows_js_1.3/themes/mac_os_x.css create mode 100644 public/windows_js_1.3/themes/mac_os_x/B.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/BL.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/BL_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/BR.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/BR_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/B_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/L.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/L_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/R.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/R_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/T.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/TL.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/TL_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/TR.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/TR_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/T_Main.png create mode 100644 public/windows_js_1.3/themes/mac_os_x/close.gif create mode 100644 public/windows_js_1.3/themes/mac_os_x/maximize.gif create mode 100644 public/windows_js_1.3/themes/mac_os_x/minimize.gif create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog.css create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/B.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/BL.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/BR.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/L.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/R.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/T.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/TL.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/TR.png create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/bg.gif create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/close.gif create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/maximize.gif create mode 100644 public/windows_js_1.3/themes/mac_os_x_dialog/minimize.gif create mode 100644 public/windows_js_1.3/themes/nuncio.css create mode 100644 public/windows_js_1.3/themes/nuncio/bottom_left.png create mode 100644 public/windows_js_1.3/themes/nuncio/bottom_mid.png create mode 100644 public/windows_js_1.3/themes/nuncio/bottom_right.png create mode 100644 public/windows_js_1.3/themes/nuncio/center_left.png create mode 100644 public/windows_js_1.3/themes/nuncio/center_right.png create mode 100644 public/windows_js_1.3/themes/nuncio/close.png create mode 100644 public/windows_js_1.3/themes/nuncio/minimize.png create mode 100644 public/windows_js_1.3/themes/nuncio/overlay.png create mode 100644 public/windows_js_1.3/themes/nuncio/top_left.png create mode 100644 public/windows_js_1.3/themes/nuncio/top_mid.png create mode 100644 public/windows_js_1.3/themes/nuncio/top_right.png create mode 100644 public/windows_js_1.3/themes/spread.css create mode 100644 public/windows_js_1.3/themes/spread/.gif create mode 100644 public/windows_js_1.3/themes/spread/bottom-left-c.gif create mode 100644 public/windows_js_1.3/themes/spread/bottom-middle.gif create mode 100644 public/windows_js_1.3/themes/spread/bottom-right-c.gif create mode 100644 public/windows_js_1.3/themes/spread/button-close-focus.gif create mode 100644 public/windows_js_1.3/themes/spread/button-max-focus.gif create mode 100644 public/windows_js_1.3/themes/spread/button-min-focus.gif create mode 100644 public/windows_js_1.3/themes/spread/frame-left.gif create mode 100644 public/windows_js_1.3/themes/spread/frame-right.gif create mode 100644 public/windows_js_1.3/themes/spread/left-top.gif create mode 100644 public/windows_js_1.3/themes/spread/right-top.gif create mode 100644 public/windows_js_1.3/themes/spread/top-middle.gif create mode 100644 start.bat diff --git a/JIRC.js b/JIRC.js new file mode 100644 index 0000000..f68f4e3 --- /dev/null +++ b/JIRC.js @@ -0,0 +1,178 @@ +#!/usr/bin/env node + +//growl('5 new emails', { title: 'Email Client' }); +//process.exit(0); +var argv = require('optimist').argv, bindhost="127.0.0.1", bindport="10080"; +if(argv.h || argv.help){ + console.log('usage: '+argv.$0+' [options] [bind-host]'); + console.log(''); + console.log('Options:'); + console.log('-q be quiet'); + console.log('-v verbose logging'); + process.exit(0); +} +if(argv._[0]){ + if(argv._[0].match(/^\d+\.\d+\.\d+\.\d+\:[0-9]{1,5}$/)){ + bindhost=argv._[0].split(":")[0]; + bindport=argv._[0].split(":")[1]; + } else { + console.error('Error: bind-host must be in the format [IP]:[PORT]'); + process.exit(0); + } +} + +require('./lib/IRC.js'); +global.argv=argv; +global.irc.loadScripts(); +global.settings = ''; +global.resume = ''; + +var http = require('http'), + WebSocketRequest = require('websocket').request, + ws = require('websocket-server'), + url = require('url'), + fs = require('fs'), + static = require('node-static'), + file = new(static.Server)('./public', { cache: 7200, headers: {'X-Hello':'World!'} }), + httpServer = http.createServer(function(request, response) { + var queryData = ""; + request.on('data', function(data) { + var path = url.parse(request.url).pathname; + if(path=="/resume"){ + queryData += data; + if(queryData.length > 1e6) { + queryData = ""; + response.writeHead(413, {'Content-Type': 'text/plain'}); + request.connection.destroy(); + } + } else if(path=="/settings"){ + queryData += data; + if(queryData.length > 1e6) { + queryData = ""; + response.writeHead(413, {'Content-Type': 'text/plain'}); + request.connection.destroy(); + } + } + }); + + request.addListener('end', function () { + var path = url.parse(request.url).pathname; + if(path=="/emoticons"){ + var emoticons = fs.readFileSync( + __dirname + '/public/images/emoticons/Emoticons.plist', 'utf8' + ); + response.writeHead(200, {"Content-Type": "application/xml"}); + response.end(emoticons); + } else if(path=="/resume"){ + response.writeHead(200, {"Content-Type": "application/json"}); + response.end(JSON.stringify(global.resume)); + if(queryData) { + global.resume=JSON.parse(queryData); + } + } else if(path=="/settings"){ + response.writeHead(200, {"Content-Type": "application/json"}); + response.end(JSON.stringify(global.settings)); + if(queryData) { + global.settings=JSON.parse(queryData); + } + } else{ + file.serve(request, response, function (err, res) { + if (err) { + console.error((new Date()) + " > Error serving " + request.url + " - " + err.message); + response.writeHead(err.status, err.headers); + response.end(); + } else { + if(argv.v) console.log((new Date()) + " > " + request.url + " - " + res.message); + } + }); + } + }); + }); +httpServer.listen(bindport, bindhost, function() { + if(!argv.q) console.log((new Date()) + " Server is listening on " + bindhost + ":" + bindport); +}); + +// node-websocket-server +var miksagoConnection = require('./node_modules/websocket-server/lib/ws/connection'); +var miksagoServer = ws.createServer(); +miksagoServer.server = httpServer; +miksagoServer.addListener('connection', function(connection) { + connection.remoteAddress = connection._socket.remoteAddress; + connection.sendUTF = connection.send; + handleConnection(connection); +}); + + +// WebSocket-Node config + +var wsServerConfig = { + // All options *except* 'httpServer' are required when bypassing + // WebSocketServer. + maxReceivedFrameSize: 0x10000, + maxReceivedMessageSize: 0x100000, + fragmentOutgoingMessages: true, + fragmentationThreshold: 0x4000, + keepalive: true, + keepaliveInterval: 20000, + assembleFragments: true, + // autoAcceptConnections is not applicable when bypassing WebSocketServer + // autoAcceptConnections: false, + disableNagleAlgorithm: true, + closeTimeout: 5000 +}; + +httpServer.on('upgrade', function(req, socket, head) { + if (typeof req.headers['sec-websocket-version'] !== 'undefined') { + // WebSocket hybi-08/-09/-10 connection (WebSocket-Node) + var wsRequest = new WebSocketRequest(socket, req, wsServerConfig); + try { + wsRequest.readHandshake(); + var wsConnection = wsRequest.accept(wsRequest.requestedProtocols[0], wsRequest.origin); + handleConnection(wsConnection); + } + catch(e) { + console.log("WebSocket Request unsupported by WebSocket-Node: " + e.toString()); + return; + } + } else { + // WebSocket hixie-75/-76/hybi-00 connection (node-websocket-server) + if (req.method === 'GET' && + (req.headers.upgrade && req.headers.connection) && + req.headers.upgrade.toLowerCase() === 'websocket' && + req.headers.connection.toLowerCase() === 'upgrade') { + new miksagoConnection(miksagoServer.manager, miksagoServer.options, req, socket, head); + } + } +}); + +function handleConnection(connection) { + if(!argv.q) console.log((new Date()) + " Connection accepted."); + global.websocket = connection; + connection.addListener('message', function(wsMessage) { + var message = wsMessage; + // WebSocket-Node adds a "type", node-websocket-server does not + if (typeof wsMessage.type !== 'undefined') { + if (wsMessage.type !== 'utf8') { + return; + } + message = wsMessage.utf8Data; + } +// console.log("Received Message: " + message); + if (message.match(/^CONNECT (.*)$/i)) { + var arrCmd = message.split(" "); + global.irc.connect(arrCmd[1], arrCmd[2], arrCmd[3], arrCmd[4], arrCmd[5], arrCmd[6]); + } else{ + global.irc.send(message); + } + }); + + connection.addListener('close', function() { + if(!argv.q) console.log((new Date()) + " Peer " + connection.remoteAddress + " disconnected."); + if(!global.resume || global.settings.hold != "on") { + global.irc.quit('BYE BYE'); + if(!argv.q) console.log((new Date()) + " Disconnected from IRC"); + } + }); + +} +if(!argv.n) require("openurl").open("http://" + bindhost + ":" + bindport); diff --git a/README b/README new file mode 100644 index 0000000..b29838f --- /dev/null +++ b/README @@ -0,0 +1,62 @@ +JIRC: An IRC client based on websocket +====================================== + + +Release Notes +------------- + +Please do not share the code without my permission. +This is Beta-Software and not ready for the masses. +There will be a public version with 1.0. +Feel free to modify and improve the code, +but please send me your improvements. + + +Changelog +--------- + +- Connection-Settings will be saved now using local storage +- Colors (and color stripping) are now working correctly + (0000002, 0000009) +- Username and realname are now filled automatically + if user types in a nickname in the connection dialog +- Connection dialog has now a field for server-password + (0000005) +- Button title of channel becomes blue on new messages, + if the window stays in background (0000008) +- Minor bug fixes (0000003,0000004,0000006,0000007,0000010) + + +Known Issues +------------ + +- No error-handling in the backend +- No error-handling in UI-dialogs +- Wrong size of user-list while changing size +- Only one connection per time allowed +- Not multi-user ready + + +Browser Support +--------------- + +- Tested Browsers: + Firefox 16 + Safari 6 + to be continued ... + +- Browsers that should work: + Chrome 14+ + Firefox 7+ + Safari 5+ + Opera ? + Internet Explorer 9+ + + +Installation +------------ + +1. Download and install NodeJS from http://nodejs.org +2. open a terminal and cd into the JIRC-directory +3. type in "node JIRC.js" +4. that's it diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..5513e40 --- /dev/null +++ b/README.txt @@ -0,0 +1,63 @@ +JIRC: An IRC client based on websocket +====================================== + + +Release Notes +------------- + +Please do not share the code without my permission. +This is Beta-Software and not ready for the masses. +There will be a public version with 1.0. +Feel free to modify and improve the code, +but please send me your improvements. + + +Changelog +--------- + +- Connection-Settings will be saved now using local storage +- Colors (and color stripping) are now working correctly + (0000002, 0000009) +- Username and realname are now filled automatically + if user types in a nickname in the connection dialog +- Connection dialog has now a field for server-password + (0000005) +- Button title of channel becomes blue on new messages, + if the window stays in background (0000008) +- Minor bug fixes (0000003,0000004,0000006,0000007,0000010) + + +Known Issues +------------- + +- No error-handling in the backend +- No error-handling in UI-dialogs +- no saving of connection-settings +- Wrong size of user-list while changing size +- Only one connection per time allowed +- Not multi-user ready + + +Browser Support +---------------- + +Tested Browsers: + +Firefox 16 +Safari 6 to be continued ... + +- Browsers that should work: + Chrome 14+ + Firefox 7+ + Safari 5+ + Opera ? + Internet Explorer 9+ + + +Installation +------------ + +1. Download and install NodeJS from http://nodejs.org +2. open a terminal and cd into the JIRC-directory +3. type in "node JIRC.js" +4. that's it \ No newline at end of file diff --git a/lib/IRC.js b/lib/IRC.js new file mode 100644 index 0000000..d14a5da --- /dev/null +++ b/lib/IRC.js @@ -0,0 +1,458 @@ +var Buffer = require('buffer').Buffer; + +var Utf8Decoder = exports.Utf8Decoder = function() { + this.charBuffer = new Buffer(4); + this.charReceived = 0; + this.charLength = 0; +}; + +Utf8Decoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + if (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var i = (buffer.length >= this.charLength - this.charReceived) + ? this.charLength - this.charReceived + : buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, i); + this.charReceived += i; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return; + } + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(); + this.charReceived = this.charLength = 0; + + if (i == buffer.length) { + // if there are no more bytes in this buffer, just emit our char + this.onString(charStr) + return; + } + + // otherwise cut of the characters end from the beginning of this buffer + buffer = buffer.slice(i, buffer.length); + } + + + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) + ? 3 + : buffer.length; + + // figure out if one of the last i bytes of our buffer announces an incomplete char + for (; i > 0; i--) { + c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + + if (!this.charLength) { + // no incomplete char at the end of this buffer, emit the whole thing + this.onString(charStr+buffer.toString()); + return; + } + + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - i, buffer.length); + this.charReceived = i; + + if (buffer.length - i > 0) { + // buffer had more bytes before the incomplete char, emit them + this.onString(charStr+buffer.slice(0, buffer.length - i).toString()); + } else if (charStr) { + // or just emit the charStr if any + this.onString(charStr); + } +}; + +global.irc = new function () { +// require('./config.js'); + +var util = require('util'), + net = require('net'), + fs = require('fs'), + vm = require('vm'), + repl = require('repl'), + _ = require('underscore'), + growl = require('growl'), + request = require('request'); + // var buffer, ignoredb, listeners, socket; + var buffer, listener, socket; + socket = new net.Socket(); + socket.setNoDelay(true); + socket.setEncoding('utf8'); + buffer = { + b: new Buffer(4096), +// b: new Utf8Decoder(), + size: 0 + }; + listeners = []; +// ignoredb = listdb.getDB('ignore'); + this.send = send; + this.nickname = ''; + function send(data) { + if (!data || data.length == 0) { + console.log("ERROR tried to send no data"); + return; + } else if (data.length > 510) { + console.log("ERROR tried to send data > 510 chars in length: " + data); + return; + } + socket.write(data + '\r\n', 'utf8', function () { + if(global.argv.v) console.log("-> " + data); + websocket.sendUTF("-> " + data); + }); + } + + socket.on('data', function (data) { + var newlineIdx; + data = data.replace('\r', ''); + while ((newlineIdx = data.indexOf('\n')) > -1) { + if (buffer.size > 0) { + if(data.match(/[^\x09\x0A\x0D\x20-\xD7FF\xE000-\xFFFD\x10000-x10FFFF]/)) { + } else { + data = data.toString('utf8', 0, buffer.size) + data; + } + newlineIdx += buffer.size; + buffer.size = 0; + } + handle(data.substr(0, newlineIdx)); + data = data.slice(newlineIdx + 1); + } + if (data.length > 0) { + buffer.b.write(data, buffer.size); + buffer.size += data.length; + } + }); + + function sendNotification(nick, msg, type) { + if(global.settings.ooh == "on" && global.websocket.connected) return; + if(global.settings.growl == "on") { + growl('<' + nick + '> ' + msg, { title: 'New ' + type }); + } + if(global.settings.prowl == "on" && global.settings.prowlkey) { + var priority = global.settings.prowlpriority || 0; + request.post( + 'https://api.prowlapp.com/publicapi/add', + { form: { apikey:global.settings.prowlkey, priority:priority, application:'JIRC', event:'New' + type, description:'<' + nick + '> ' + msg } }, + function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log('Prowl Notification sent'); + } + } + ); + } + if(global.settings.nma == "on" && global.settings.nmakey) { + var priority = global.settings.nmapriority || 0; + request.post( + 'https://www.notifymyandroid.com/publicapi/notify', + { form: { apikey:global.settings.nmakey, priority:priority, application:'JIRC', event:'New' + type, description:'<' + nick + '> ' + msg } }, + function (error, response, body) { + if (!error && response.statusCode == 200) { + console.log('NMA Notification sent'); + } + } + ); + } + } + + function handle (data) { + var dest, i, user, replyTo; + if(global.argv.v) console.log("<- " + data); + global.websocket.sendUTF('<- ' + data); + user = (/^:([^!]+)!/i).exec(data); + if (user) { + user = user[1]; +/* + if (ignoredb.hasValue(user, true)) { + return; + } +*/ + } + replyTo = null; + if (data.indexOf('PRIVMSG') > -1) { + dest = (/^:([^!]+)!.*PRIVMSG ([^ ]+) [\: ](.+)/i).exec(data); + if (dest) { + if (dest[2].toUpperCase() == global.nickname.toUpperCase()) { + if(global.settings) sendNotification(dest[1], dest[3], 'Private Message'); + replyTo = dest[1]; + } else { + if (dest[3].toUpperCase().indexOf(global.nickname.toUpperCase()) > -1 && global.settings) sendNotification(dest[1], dest[3], 'Highlight'); + replyTo = dest[2]; + } + } + } + if (data.match(/^PING :(.+)/)) { + send('PONG :' + data.match(/^PING :(.+)/)[1]); + } + var match, regex; + for (i = 0; i < listeners.length; i++) { + if(_.isRegExp(listeners[i][0])) { + match = listeners[i][0].exec(data); + } else { + regex = 'PRIVMSG [^ ]+ :'; + if(listeners[i][3] /* prefixed */) { +// regex += nodebot_prefs.command_prefix; + regex += "~" + } + regex += listeners[i][0]; + regex = new RegExp(regex); + match = regex.exec(data); + } + + if (match) { + try { + listeners[i][1](match, data, replyTo); + } catch (err) { + console.log("caught error in script " + listeners[i][3] + ": " + err); + } + if (listeners[i][2] /* once */) { + listeners.splice(i, 1); + i--; + } + } + } + } + + function sanitize (data) { + if (!data) { + return data; + } + /* Note: + * 0x00 (null character) is invalid + * 0x01 signals a CTCP message, which we shouldn't ever need to do + * 0x02 is bold in mIRC (and thus other GUI clients) + * 0x03 precedes a color code in mIRC (and thus other GUI clients) + * 0x04 thru 0x19 are invalid control codes, except for: + * 0x16 is "reverse" (swaps fg and bg colors) in mIRC + */ + // return data.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[^\x02-\x03|\x16|\x20-\x7e]/g, ""); + return data.replace(/\n/g, "\\n").replace(/\r/g, "\\r"); + } + this.privmsg = function (user, message) { + if (user && message) { + user = sanitize(user); //avoid sanitizing these more than once + message = sanitize(message); + + var privmsg = "PRIVMSG " + user + " :"; + var max = 510 - privmsg.length; + + var maxmessages = 3; + while (message && (maxmessages--) > 0) { + send(privmsg + message.slice(0, max)); + message = message.slice(max); + } + } + }; + this.quit = function(msg) { + send('QUIT ' + msg); + socket.end(); + socket.destroy(); + } + + this.pong = function (server) { + send("PONG :" + server); +// websocket.sendUTF('-> PONG :' + server); + } + this.connect = function (host, port, pass, nickname, username, realname) { + var i = 0; + port = port || 6667; + pass = pass || ''; + global.nickname = nickname; + socket.connect(port, host, function () { + if(i==0){ + if(pass) send('PASS ' + sanitize(pass)); + send('NICK ' + sanitize(nickname)); + send('USER ' + sanitize(username) + ' localhost * ' + sanitize(realname)); + i=1; + } + }); + } + + this.loadScripts = function () { + var i, k, script, scripts; + socket.pause(); + listeners = []; + scripts = fs.readdirSync('scripts'); + if (scripts) { + for (i = 0; i < scripts.length; i++) { + if (scripts[i].substr(-3) == '.js' && + scripts[i].substr(-9) != '.child.js') { + if(global.argv.v) console.log("Loading script " + scripts[i] + "..."); + script = fs.readFileSync('scripts/' + scripts[i]); + if (script) { + var scriptName = scripts[i]; + var sandbox = { + irc: irc, +// nodebot_prefs: nodebot_prefs, + console: console, + setTimeout: setTimeout, + setInterval: setInterval, + vm: vm, + fs: fs, + require: require, + util: util, + listen: function (dataRegex, callback, once, prefixed) { + once = !!once; + if (typeof prefixed === "undefined" || prefixed === null) { + prefixed = true; + } + listeners.push([dataRegex, callback, once, prefixed, scriptName]); + } + }; + try { + vm.runInNewContext(script, sandbox, scripts[i]); + } catch (err) { + console.log("Error in script " + scripts[i] + ": " + err); + for (j = 0; j < listeners.length; j++) { + if (listeners[j][3] == scriptName) { + listeners.splice(j, 1); + j--; + } + } + } + } + } + } + } + try { + socket.resume(); + } catch (err) {} + if(global.argv.v) console.log("Scripts loaded."); + } + +/* + return { + raw: function(stuff) { + send(stuff); + }, + connect: function (host, port, nickname, username, realname) { + port = port || 6667; + socket.connect(port, host, function () { + send('NICK ' + sanitize(nickname)); + send('USER ' + sanitize(username) + ' localhost * ' + sanitize(realname)); + }); + }, + loadScripts: function () { + var i, k, script, scripts; + socket.pause(); + listeners = []; + scripts = fs.readdirSync('scripts'); + if (scripts) { + for (i = 0; i < scripts.length; i++) { + if (scripts[i].substr(-3) == '.js' && + scripts[i].substr(-9) != '.child.js') { + console.log("Loading script " + scripts[i] + "..."); + script = fs.readFileSync('scripts/' + scripts[i]); + if (script) { + var scriptName = scripts[i]; + var sandbox = { + irc: irc, + nodebot_prefs: nodebot_prefs, + console: console, + setTimeout: setTimeout, + setInterval: setInterval, + vm: vm, + fs: fs, + require: require, + util: util, + listen: function (dataRegex, callback, once, prefixed) { + once = !!once; + if (typeof prefixed === "undefined" || prefixed === null) { + prefixed = true; + } + listeners.push([dataRegex, callback, once, prefixed, scriptName]); + } + }; + try { + vm.runInNewContext(script, sandbox, scripts[i]); + } catch (err) { + console.log("Error in script " + scripts[i] + ": " + err); + for (j = 0; j < listeners.length; j++) { + if (listeners[j][3] == scriptName) { + listeners.splice(j, 1); + j--; + } + } + } + } + } + } + } + try { + socket.resume(); + } catch (err) {} + console.log("Scripts loaded."); + }, + + pong: function (server) { + send("PONG :" + server); + }, + join: function (channel, key) { + var cmd = "JOIN :" + sanitize(channel); + if (key) { + cmd += " " + sanitize(key); + } + send(cmd); + }, + part: function (channel) { + send("PART :" + sanitize(channel)); + }, + privmsg: function (user, message) { + if (user && message) { + user = sanitize(user); //avoid sanitizing these more than once + message = sanitize(message); + + var privmsg = "PRIVMSG " + user + " :"; + var max = 510 - privmsg.length; + + var maxmessages = 3; + while (message && (maxmessages--) > 0) { + send(privmsg + message.slice(0, max)); + message = message.slice(max); + } + } + }, + action: function (channel, action) { + if (channel && action) { + send("PRIVMSG " + sanitize(channel) + " :\x01ACTION " + sanitize(action) + "\x01"); + } + }, + test: function() { + console.log('TEST'); + } + ignore: function (user) { + ignoredb.add(user); + }, + unignore: function (user) { + ignoredb.remove(user, true); + }, + chatignorelist: function (channel) { + irc.chatmsg(channel, "Ignore list: " + sanitize(ignoredb.getAll().join(","))); + } + } +*/ +} diff --git a/lib/entities.js b/lib/entities.js new file mode 100644 index 0000000..0009ee0 --- /dev/null +++ b/lib/entities.js @@ -0,0 +1,291 @@ +var entities = { + ' ': '\u00a0', + '¡': '\u00a1', + '¢': '\u00a2', + '£': '\u00a3', + '€': '\u20ac', + '¥': '\u00a5', + '¦': '\u0160', + '§': '\u00a7', + '¨': '\u0161', + '©': '\u00a9', + 'ª': '\u00aa', + '«': '\u00ab', + '¬': '\u00ac', + '­': '\u00ad', + '®': '\u00ae', + '¯': '\u00af', + '°': '\u00b0', + '±': '\u00b1', + '²': '\u00b2', + '³': '\u00b3', + '´': '\u017d', + 'µ': '\u00b5', + '¶': '\u00b6', + '·': '\u00b7', + '¸': '\u017e', + '¹': '\u00b9', + 'º': '\u00ba', + '»': '\u00bb', + '¼': '\u0152', + '½': '\u0153', + '¾': '\u0178', + '¿': '\u00bf', + 'À': '\u00c0', + 'Á': '\u00c1', + 'Â': '\u00c2', + 'Ã': '\u00c3', + 'Ä': '\u00c4', + 'Å': '\u00c5', + 'Æ': '\u00c6', + 'Ç': '\u00c7', + 'È': '\u00c8', + 'É': '\u00c9', + 'Ê': '\u00ca', + 'Ë': '\u00cb', + 'Ì': '\u00cc', + 'Í': '\u00cd', + 'Î': '\u00ce', + 'Ï': '\u00cf', + 'Ð': '\u00d0', + 'Ñ': '\u00d1', + 'Ò': '\u00d2', + 'Ó': '\u00d3', + 'Ô': '\u00d4', + 'Õ': '\u00d5', + 'Ö': '\u00d6', + '×': '\u00d7', + 'Ø': '\u00d8', + 'Ù': '\u00d9', + 'Ú': '\u00da', + 'Û': '\u00db', + 'Ü': '\u00dc', + 'Ý': '\u00dd', + 'Þ': '\u00de', + 'ß': '\u00df', + 'à': '\u00e0', + 'á': '\u00e1', + 'â': '\u00e2', + 'ã': '\u00e3', + 'ä': '\u00e4', + 'å': '\u00e5', + 'æ': '\u00e6', + 'ç': '\u00e7', + 'è': '\u00e8', + 'é': '\u00e9', + 'ê': '\u00ea', + 'ë': '\u00eb', + 'ì': '\u00ec', + 'í': '\u00ed', + 'î': '\u00ee', + 'ï': '\u00ef', + 'ð': '\u00f0', + 'ñ': '\u00f1', + 'ò': '\u00f2', + 'ó': '\u00f3', + 'ô': '\u00f4', + 'õ': '\u00f5', + 'ö': '\u00f6', + '÷': '\u00f7', + 'ø': '\u00f8', + 'ù': '\u00f9', + 'ú': '\u00fa', + 'û': '\u00fb', + 'ü': '\u00fc', + 'ý': '\u00fd', + 'þ': '\u00fe', + 'ÿ': '\u00ff', + '"': '\u0022', + '<': '\u003c', + '>': '\u003e', + ''': '\u0027', + '−': '\u2212', + 'ˆ': '\u02c6', + '˜': '\u02dc', + 'Š': '\u0160', + '‹': '\u2039', + 'Œ': '\u0152', + '‘': '\u2018', + '’': '\u2019', + '“': '\u201c', + '”': '\u201d', + '•': '\u2022', + '–': '\u2013', + '—': '\u2014', + '™': '\u2122', + 'š': '\u0161', + '›': '\u203a', + 'œ': '\u0153', + 'Ÿ': '\u0178', + 'ƒ': '\u0192', + 'Α': '\u0391', + 'Β': '\u0392', + 'Γ': '\u0393', + 'Δ': '\u0394', + 'Ε': '\u0395', + 'Ζ': '\u0396', + 'Η': '\u0397', + 'Θ': '\u0398', + 'Ι': '\u0399', + 'Κ': '\u039a', + 'Λ': '\u039b', + 'Μ': '\u039c', + 'Ν': '\u039d', + 'Ξ': '\u039e', + 'Ο': '\u039f', + 'Π': '\u03a0', + 'Ρ': '\u03a1', + 'Σ': '\u03a3', + 'Τ': '\u03a4', + 'Υ': '\u03a5', + 'Φ': '\u03a6', + 'Χ': '\u03a7', + 'Ψ': '\u03a8', + 'Ω': '\u03a9', + 'α': '\u03b1', + 'β': '\u03b2', + 'γ': '\u03b3', + 'δ': '\u03b4', + 'ε': '\u03b5', + 'ζ': '\u03b6', + 'η': '\u03b7', + 'θ': '\u03b8', + 'ι': '\u03b9', + 'κ': '\u03ba', + 'λ': '\u03bb', + 'μ': '\u03bc', + 'ν': '\u03bd', + 'ξ': '\u03be', + 'ο': '\u03bf', + 'π': '\u03c0', + 'ρ': '\u03c1', + 'ς': '\u03c2', + 'σ': '\u03c3', + 'τ': '\u03c4', + 'υ': '\u03c5', + 'φ': '\u03c6', + 'χ': '\u03c7', + 'ψ': '\u03c8', + 'ω': '\u03c9', + 'ϑ': '\u03d1', + 'ϒ': '\u03d2', + 'ϖ': '\u03d6', + ' ': '\u2002', + ' ': '\u2003', + ' ': '\u2009', + '‌': '\u200c', + '‍': '\u200d', + '‎': '\u200e', + '‏': '\u200f', + '‚': '\u201a', + '„': '\u201e', + '†': '\u2020', + '‡': '\u2021', + '…': '\u2026', + '‰': '\u2030', + '′': '\u2032', + '″': '\u2033', + '‾': '\u203e', + '⁄': '\u2044', + '€': '\u20ac', + 'ℑ': '\u2111', + '℘': '\u2118', + 'ℜ': '\u211c', + 'ℵ': '\u2135', + '←': '\u2190', + '↑': '\u2191', + '→': '\u2192', + '↓': '\u2193', + '↔': '\u2194', + '↵': '\u21b5', + '⇐': '\u21d0', + '⇑': '\u21d1', + '⇒': '\u21d2', + '⇓': '\u21d3', + '⇔': '\u21d4', + '∀': '\u2200', + '∂': '\u2202', + '∃': '\u2203', + '∅': '\u2205', + '∇': '\u2207', + '∈': '\u2208', + '∉': '\u2209', + '∋': '\u220b', + '∏': '\u220f', + '∑': '\u2211', + '∗': '\u2217', + '√': '\u221a', + '∝': '\u221d', + '∞': '\u221e', + '∠': '\u2220', + '∧': '\u2227', + '∨': '\u2228', + '∩': '\u2229', + '∪': '\u222a', + '∫': '\u222b', + '∴': '\u2234', + '∼': '\u223c', + '≅': '\u2245', + '≈': '\u2248', + '≠': '\u2260', + '≡': '\u2261', + '≤': '\u2264', + '≥': '\u2265', + '⊂': '\u2282', + '⊃': '\u2283', + '⊄': '\u2284', + '⊆': '\u2286', + '⊇': '\u2287', + '⊕': '\u2295', + '⊗': '\u2297', + '⊥': '\u22a5', + '⋅': '\u22c5', + '⌈': '\u2308', + '⌉': '\u2309', + '⌊': '\u230a', + '⌋': '\u230b', + '⟨': '\u2329', + '⟩': '\u232a', + '◊': '\u25ca', + '♠': '\u2660', + '♣': '\u2663', + '♥': '\u2665', + '♦': '\u2666' +}; + +exports.decode = function (str) { + if (!~str.indexOf('&')) return str; + + //Decode literal entities + for (var i in entities) { + str = str.replace(new RegExp(i, 'g'), entities[i]); + } + + //Decode hex entities + str = str.replace(/&#x(0*[0-9a-f]{2,5});?/gi, function (m, code) { + return String.fromCharCode(parseInt(+code, 16)); + }); + + //Decode numeric entities + str = str.replace(/&#([0-9]{2,4});?/gi, function (m, code) { + return String.fromCharCode(+code); + }); + + str = str.replace(/&/g, '&'); + + return str; +} + +exports.encode = function (str) { + str = str.replace(/&/g, '&'); + + //IE doesn't accept ' + str = str.replace(/'/g, '''); + + //Encode literal entities + for (var i in entities) { + str = str.replace(new RegExp(entities[i], 'g'), i); + } + + return str; +} diff --git a/lib/entities.js.LICENSE b/lib/entities.js.LICENSE new file mode 100644 index 0000000..c1a825a --- /dev/null +++ b/lib/entities.js.LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2010 Chris O'Hara + +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. diff --git a/lib/googleweather.js b/lib/googleweather.js new file mode 100644 index 0000000..70c7b59 --- /dev/null +++ b/lib/googleweather.js @@ -0,0 +1,120 @@ +/* Modified version of node-googleweather by maxkueng + * (Removed the celsius and kmh conversions) + * Original library can be found at: + * https://github.com/maxkueng/node-googleweather/ + * +MIT License + +Copyright (c) 2011 Max Kueng (http://maxkueng.com/) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +var request = require('request'); +var jsdom = require('jsdom'); + +Date.prototype.pad = function (n) { + return (n < 10) ? '0' + n : n; +}; + +Date.prototype.toISODate = function () { + return this.getFullYear() + '-' + + this.pad(this.getMonth() + 1) + '-' + + this.pad(this.getDate()); +}; + +var get = function (callback, location, forecastDate) { + var currentConditions = { + 'date' : null, + 'condition' : null, + 'temperature' : null, + 'humidity' : null, + 'wind' : { + 'direction' : null, + 'speed' : null + } + }; + + var forecast = []; + + var uri = 'http://www.google.com/ig/api?weather=' + + escape(location); + + request({ + 'method' : 'GET', + 'uri' : uri, + 'headers' : { + 'User-Agent' : 'Nintendo Gameboy/1.0' + } + }, function (error, response, body) { + if (!error && response.statusCode == 200) { + jsdom.env(body, [], + function(errors, window) { + try { + var document = window.document; + var info = document.getElementsByTagName('forecast_information')[0]; + var current = document.getElementsByTagName('current_conditions')[0]; + var forecasts = document.getElementsByTagName('forecast_conditions'); + + var baseDateString = info.getElementsByTagName('forecast_date')[0].getAttribute('data'); + var baseDate = new Date(baseDateString); + + currentConditions.date = baseDateString; + currentConditions.condition = current.getElementsByTagName('condition')[0].getAttribute('data'); + currentConditions.temperature = current.getElementsByTagName('temp_f')[0].getAttribute('data'); + + var humidityString = current.getElementsByTagName('humidity')[0].getAttribute('data'); + currentConditions.humidity = /(\d+)%/.exec(humidityString)[1]; + + var windString = current.getElementsByTagName('wind_condition')[0].getAttribute('data'); + var windMatches = /([NESW]+)\sat\s([0-9]+)\smph/.exec(windString); + currentConditions.wind.direction = windMatches[1]; + currentConditions.wind.speed = windMatches[2]; + + for (var i = 0; i < forecasts.length; i++) { + var d = new Date(baseDate.getTime() + ( i * 24 * 3600 * 1000 )); + var condition = forecasts[i].getElementsByTagName('condition')[0].getAttribute('data'); + var lowTemp = forecasts[i].getElementsByTagName('low')[0].getAttribute('data'); + var highTemp = forecasts[i].getElementsByTagName('high')[0].getAttribute('data'); + + var forecastDay = { + 'date' : d.toISODate(), + 'condition' : condition, + 'temperature' : { + 'low' : lowTemp, + 'high' : highTemp + } + }; + + forecast[d.toISODate()] = forecastDay; + } + + callback(currentConditions, forecast[forecastDate]); + } catch(err) { + callback(null, null); + return; + } + } + ); + } + }); +}; + +exports.get = get; diff --git a/lib/listdb.js b/lib/listdb.js new file mode 100644 index 0000000..bb81d89 --- /dev/null +++ b/lib/listdb.js @@ -0,0 +1,78 @@ +// (c) 2011 Richard Carter +// This code is licensed under the MIT license; see LICENSE.txt for details. + +// A list db is a file-backed list of strings; the strings should not have +// the newline character in them, but otherwise can be arbitrary length. +// The db file is stored in "data/DBNAME.list". + +var fs = require('fs'); + +exports.getDB = function (dbName) { + var fileName = 'data/'+dbName+'.txt'; + var values; + + try { + values = fs.readFileSync(fileName, 'ascii'); + if(values && values.length > 0) { + values = values.split('\n'); + } else { + values = []; + } + } catch(err) {values = [];} + + function writeFile() { + fs.writeFileSync(fileName, values.join('\n'), 'ascii'); + } + + return { + getName: function () { + return dbName; + }, + getAll: function() { + return values; + }, + hasValue: function (value, ignoreCase) { + ignoreCase = ignoreCase || false; + + var i; + for(i=0; i= 400) { + if (callback) { + callback(result); + } else { + if (promise.listeners('error').length > 0) { + promise.emit('error', result); + } + res.writeHead(status, headers); + res.end(); + } + } else { + // Don't end the request here, if we're streaming; + // it's taken care of in `prototype.stream`. + if (status !== 200 || req.method !== 'GET') { + res.writeHead(status, headers); + res.end(); + } + callback && callback(null, result); + promise.emit('success', result); + } +}; + +this.Server.prototype.servePath = function (pathname, status, headers, req, res, finish) { + var that = this, + promise = new(events.EventEmitter); + + pathname = this.resolve(pathname); + + // Only allow GET and HEAD requests + if (req.method !== 'GET' && req.method !== 'HEAD') { + finish(405, { 'Allow': 'GET, HEAD' }); + return promise; + } + + // Make sure we're not trying to access a + // file outside of the root. + if (pathname.indexOf(that.root) === 0) { + fs.stat(pathname, function (e, stat) { + if (e) { + finish(404, {}); + } else if (stat.isFile()) { // Stream a single file. + that.respond(null, status, headers, [pathname], stat, req, res, finish); + } else if (stat.isDirectory()) { // Stream a directory of files. + that.serveDir(pathname, req, res, finish); + } else { + finish(400, {}); + } + }); + } else { + // Forbidden + finish(403, {}); + } + return promise; +}; +this.Server.prototype.resolve = function (pathname) { + return path.resolve(path.join(this.root, pathname)); +}; +this.Server.prototype.serve = function (req, res, callback) { + var that = this, + promise = new(events.EventEmitter); + + var pathname = decodeURI(url.parse(req.url).pathname); + + var finish = function (status, headers) { + that.finish(status, headers, req, res, promise, callback); + }; + + process.nextTick(function () { + that.servePath(pathname, 200, {}, req, res, finish).on('success', function (result) { + promise.emit('success', result); + }).on('error', function (err) { + promise.emit('error'); + }); + }); + if (! callback) { return promise } +}; + +this.Server.prototype.respond = function (pathname, status, _headers, files, stat, req, res, finish) { + var mtime = Date.parse(stat.mtime), + key = pathname || files[0], + headers = {}; + + // Copy default headers + for (var k in this.options.headers) { headers[k] = this.options.headers[k] } + + headers['ETag'] = JSON.stringify([stat.ino, stat.size, mtime].join('-')); + headers['Date'] = new(Date)().toUTCString(); + headers['Last-Modified'] = new(Date)(stat.mtime).toUTCString(); + + // Conditional GET + // If the "If-Modified-Since" or "If-None-Match" headers + // match the conditions, send a 304 Not Modified. + if (req.headers['if-none-match'] === headers['ETag'] || + Date.parse(req.headers['if-modified-since']) >= mtime) { + finish(304, headers); + } else { + var fileExtension = path.extname(files[0]).slice(1).toLowerCase(); + headers['Content-Length'] = stat.size; + headers['Content-Type'] = mime.contentTypes[fileExtension] || + 'application/octet-stream'; + + for (var k in _headers) { headers[k] = _headers[k] } + + res.writeHead(status, headers); + + if (req.method === 'HEAD') { + finish(200, headers); + return; + } + + // If the file was cached and it's not older + // than what's on disk, serve the cached version. + if (this.cache && (key in exports.store) && + exports.store[key].stat.mtime >= stat.mtime) { + res.end(exports.store[key].buffer); + finish(status, headers); + } else { + this.stream(pathname, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) { + if (e) { return finish(500, {}) } + exports.store[key] = { + stat: stat, + buffer: buffer, + timestamp: Date.now() + }; + finish(status, headers); + }); + } + } +}; + +this.Server.prototype.stream = function (pathname, files, buffer, res, callback) { + (function streamFile(files, offset) { + var file = files.shift(); + + if (file) { + file = file[0] === '/' ? file : path.join(pathname || '.', file); + + // Stream the file to the client + fs.createReadStream(file, { + flags: 'r', + mode: 0666 + }).on('data', function (chunk) { + chunk.copy(buffer, offset); + offset += chunk.length; + }).on('close', function () { + streamFile(files, offset); + }).on('error', function (err) { + callback(err); + console.error(err); + }).pipe(res, { end: false }); + } else { + res.end(); + callback(null, buffer, offset); + } + })(files.slice(0), 0); +}; diff --git a/lib/node-static/mime.js b/lib/node-static/mime.js new file mode 100644 index 0000000..dc2f79b --- /dev/null +++ b/lib/node-static/mime.js @@ -0,0 +1,140 @@ +this.contentTypes = { + "aiff": "audio/x-aiff", + "arj": "application/x-arj-compressed", + "asf": "video/x-ms-asf", + "asx": "video/x-ms-asx", + "au": "audio/ulaw", + "avi": "video/x-msvideo", + "bcpio": "application/x-bcpio", + "ccad": "application/clariscad", + "cod": "application/vnd.rim.cod", + "com": "application/x-msdos-program", + "cpio": "application/x-cpio", + "cpt": "application/mac-compactpro", + "csh": "application/x-csh", + "css": "text/css", + "deb": "application/x-debian-package", + "dl": "video/dl", + "doc": "application/msword", + "drw": "application/drafting", + "dvi": "application/x-dvi", + "dwg": "application/acad", + "dxf": "application/dxf", + "dxr": "application/x-director", + "etx": "text/x-setext", + "ez": "application/andrew-inset", + "fli": "video/x-fli", + "flv": "video/x-flv", + "gif": "image/gif", + "gl": "video/gl", + "gtar": "application/x-gtar", + "gz": "application/x-gzip", + "hdf": "application/x-hdf", + "hqx": "application/mac-binhex40", + "htm": "text/html", + "html": "text/html", + "ice": "x-conference/x-cooltalk", + "ico": "image/x-icon", + "ief": "image/ief", + "igs": "model/iges", + "ips": "application/x-ipscript", + "ipx": "application/x-ipix", + "jad": "text/vnd.sun.j2me.app-descriptor", + "jar": "application/java-archive", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "js": "text/javascript", + "json": "application/json", + "latex": "application/x-latex", + "less": "text/css", + "lsp": "application/x-lisp", + "lzh": "application/octet-stream", + "m": "text/plain", + "m3u": "audio/x-mpegurl", + "man": "application/x-troff-man", + "manifest": "text/cache-manifest", + "me": "application/x-troff-me", + "midi": "audio/midi", + "mif": "application/x-mif", + "mime": "www/mime", + "movie": "video/x-sgi-movie", + "mp4": "video/mp4", + "mpg": "video/mpeg", + "mpga": "audio/mpeg", + "ms": "application/x-troff-ms", + "nc": "application/x-netcdf", + "oda": "application/oda", + "ogm": "application/ogg", + "pbm": "image/x-portable-bitmap", + "pdf": "application/pdf", + "pgm": "image/x-portable-graymap", + "pgn": "application/x-chess-pgn", + "pgp": "application/pgp", + "pm": "application/x-perl", + "png": "image/png", + "pnm": "image/x-portable-anymap", + "ppm": "image/x-portable-pixmap", + "ppz": "application/vnd.ms-powerpoint", + "pre": "application/x-freelance", + "prt": "application/pro_eng", + "ps": "application/postscript", + "qt": "video/quicktime", + "ra": "audio/x-realaudio", + "rar": "application/x-rar-compressed", + "ras": "image/x-cmu-raster", + "rgb": "image/x-rgb", + "rm": "audio/x-pn-realaudio", + "rpm": "audio/x-pn-realaudio-plugin", + "rtf": "text/rtf", + "rtx": "text/richtext", + "scm": "application/x-lotusscreencam", + "set": "application/set", + "sgml": "text/sgml", + "sh": "application/x-sh", + "shar": "application/x-shar", + "silo": "model/mesh", + "sit": "application/x-stuffit", + "skt": "application/x-koan", + "smil": "application/smil", + "snd": "audio/basic", + "sol": "application/solids", + "spl": "application/x-futuresplash", + "src": "application/x-wais-source", + "stl": "application/SLA", + "stp": "application/STEP", + "sv4cpio": "application/x-sv4cpio", + "sv4crc": "application/x-sv4crc", + "svg": "image/svg+xml", + "swf": "application/x-shockwave-flash", + "tar": "application/x-tar", + "tcl": "application/x-tcl", + "tex": "application/x-tex", + "texinfo": "application/x-texinfo", + "tgz": "application/x-tar-gz", + "tiff": "image/tiff", + "tr": "application/x-troff", + "tsi": "audio/TSP-audio", + "tsp": "application/dsptype", + "tsv": "text/tab-separated-values", + "txt": "text/plain", + "unv": "application/i-deas", + "ustar": "application/x-ustar", + "vcd": "application/x-cdlink", + "vda": "application/vda", + "vivo": "video/vnd.vivo", + "vrm": "x-world/x-vrml", + "wav": "audio/x-wav", + "wax": "audio/x-ms-wax", + "wma": "audio/x-ms-wma", + "wmv": "video/x-ms-wmv", + "wmx": "video/x-ms-wmx", + "wrl": "model/vrml", + "wvx": "video/x-ms-wvx", + "xbm": "image/x-xbitmap", + "xlw": "application/vnd.ms-excel", + "xml": "text/xml", + "xpm": "image/x-xpixmap", + "xwd": "image/x-xwindowdump", + "xyz": "chemical/x-pdb", + "zip": "application/zip" +}; diff --git a/lib/node-static/util.js b/lib/node-static/util.js new file mode 100644 index 0000000..8dd8e04 --- /dev/null +++ b/lib/node-static/util.js @@ -0,0 +1,30 @@ +var fs = require('fs'), + path = require('path'); + +this.mstat = function (dir, files, callback) { + (function mstat(files, stats) { + var file = files.shift(); + + if (file) { + fs.stat(path.join(dir, file), function (e, stat) { + if (e) { + callback(e); + } else { + mstat(files, stats.concat([stat])); + } + }); + } else { + callback(null, { + size: stats.reduce(function (total, stat) { + return total + stat.size; + }, 0), + mtime: stats.reduce(function (latest, stat) { + return latest > stat.mtime ? latest : stat.mtime; + }, 0), + ino: stats.reduce(function (total, stat) { + return total + stat.ino; + }, 0) + }); + } + })(files.slice(0), []); +}; diff --git a/node_modules/.DS_Store b/node_modules/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ca4175f7cdaa4a30066c53538d65d9c597b7f453 GIT binary patch literal 6148 zcmeHK%}T>S5T0$TCR8C8p~uB@mHJa!!9xfYJPIxJU_}#CXrMHuN$H_RgHPa__%=R| zGrMacG-nZ=f!S|%es(t>WPboac+2nGi*@HNqqCGO%!zfHA4^CsfZeO;W@~qp(KdsjlWFkBfnU}J!XIz z_+t!+TCd;p@T1Jxy7hT<)=JbzR1(U|$v{E7a0$Q;?IR5p)Nx5R=D7xQjWi1RRXHMG N1Qa3MFatlpz!&@mLzMsk literal 0 HcmV?d00001 diff --git a/node_modules/growl/History.md b/node_modules/growl/History.md new file mode 100644 index 0000000..c408b06 --- /dev/null +++ b/node_modules/growl/History.md @@ -0,0 +1,58 @@ + +1.6.1 / 2012-09-25 +================== + + * restore compatibility with node < 0.8 [fgnass] + +1.6.0 / 2012-09-06 +================== + + * add notification center support [drudge] + +1.5.1 / 2012-04-08 +================== + + * Merge pull request #16 from KyleAMathews/patch-1 + * Fixes #15 + +1.5.0 / 2012-02-08 +================== + + * Added windows support [perfusorius] + +1.4.1 / 2011-12-28 +================== + + * Fixed: dont exit(). Closes #9 + +1.4.0 / 2011-12-17 +================== + + * Changed API: `growl.notify()` -> `growl()` + +1.3.0 / 2011-12-17 +================== + + * Added support for Ubuntu/Debian/Linux users [niftylettuce] + * Fixed: send notifications even if title not specified [alessioalex] + +1.2.0 / 2011-10-06 +================== + + * Add support for priority. + +1.1.0 / 2011-03-15 +================== + + * Added optional callbacks + * Added parsing of version + +1.0.1 / 2010-03-26 +================== + + * Fixed; sys.exec -> child_process.exec to support latest node + +1.0.0 / 2010-03-19 +================== + + * Initial release diff --git a/node_modules/growl/Readme.md b/node_modules/growl/Readme.md new file mode 100644 index 0000000..48d717c --- /dev/null +++ b/node_modules/growl/Readme.md @@ -0,0 +1,99 @@ +# Growl for nodejs + +Growl support for Nodejs. This is essentially a port of my [Ruby Growl Library](http://github.com/visionmedia/growl). Ubuntu/Linux support added thanks to [@niftylettuce](http://github.com/niftylettuce). + +## Installation + +### Install + +### Mac OS X (Darwin): + + Install [growlnotify(1)](http://growl.info/extras.php#growlnotify). On OS X 10.8, Notification Center is supported using [terminal-notifier](https://github.com/alloy/terminal-notifier). To install: + + $ sudo gem install terminal-notifier + + Install [npm](http://npmjs.org/) and run: + + $ npm install growl + +### Ubuntu (Linux): + + Install `notify-send` through the [libnotify-bin](http://packages.ubuntu.com/libnotify-bin) package: + + $ sudo apt-get install libnotify-bin + + Install [npm](http://npmjs.org/) and run: + + $ npm install growl + +### Windows: + + Download and install [Growl for Windows](http://www.growlforwindows.com/gfw/default.aspx) + + Download [growlnotify](http://www.growlforwindows.com/gfw/help/growlnotify.aspx) - **IMPORTANT :** Unpack growlnotify to a folder that is present in your path! + + Install [npm](http://npmjs.org/) and run: + + $ npm install growl + +## Examples + +Callback functions are optional + + var growl = require('growl') + growl('You have mail!') + growl('5 new messages', { sticky: true }) + growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true }) + growl('Message with title', { title: 'Title'}) + growl('Set priority', { priority: 2 }) + growl('Show Safari icon', { image: 'Safari' }) + growl('Show icon', { image: 'path/to/icon.icns' }) + growl('Show image', { image: 'path/to/my.image.png' }) + growl('Show png filesystem icon', { image: 'png' }) + growl('Show pdf filesystem icon', { image: 'article.pdf' }) + growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(err){ + // ... notified + }) + +## Options + + - title + - notification title + - name + - application name + - priority + - priority for the notification (default is 0) + - sticky + - weither or not the notification should remainin until closed + - image + - Auto-detects the context: + - path to an icon sets --iconpath + - path to an image sets --image + - capitalized word sets --appIcon + - filename uses extname as --icon + - otherwise treated as --icon + +## License + +(The MIT License) + +Copyright (c) 2009 TJ Holowaychuk + +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. diff --git a/node_modules/growl/lib/growl.js b/node_modules/growl/lib/growl.js new file mode 100644 index 0000000..3b3b611 --- /dev/null +++ b/node_modules/growl/lib/growl.js @@ -0,0 +1,232 @@ +// Growl - Copyright TJ Holowaychuk (MIT Licensed) + +/** + * Module dependencies. + */ + +var exec = require('child_process').exec + , fs = require('fs') + , path = require('path') + , exists = fs.existsSync || path.existsSync + , os = require('os') + , quote = JSON.stringify + , cmd; + +function which(name) { + var paths = process.env.PATH.split(':'); + var loc; + + for (var i = 0, len = paths.length; i < len; ++i) { + loc = path.join(paths[i], name); + if (exists(loc)) return loc; + } +} + +switch(os.type()) { + case 'Darwin': + if (which('terminal-notifier')) { + cmd = { + type: "Darwin-NotificationCenter" + , pkg: "terminal-notifier" + , msg: '-message' + , title: '-title' + , subtitle: '-subtitle' + , priority: { + cmd: '-execute' + , range: [] + } + }; + } else { + cmd = { + type: "Darwin-Growl" + , pkg: "growlnotify" + , msg: '-m' + , sticky: '--sticky' + , priority: { + cmd: '--priority' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + , "Very Low" + , "Moderate" + , "Normal" + , "High" + , "Emergency" + ] + } + }; + } + break; + case 'Linux': + cmd = { + type: "Linux" + , pkg: "notify-send" + , msg: '' + , sticky: '-t 0' + , icon: '-i' + , priority: { + cmd: '-u' + , range: [ + "low" + , "normal" + , "critical" + ] + } + }; + break; + case 'Windows_NT': + cmd = { + type: "Windows" + , pkg: "growlnotify" + , msg: '' + , sticky: '/s:true' + , title: '/t:' + , icon: '/i:' + , priority: { + cmd: '/p:' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + ] + } + }; + break; +} + +/** + * Expose `growl`. + */ + +exports = module.exports = growl; + +/** + * Node-growl version. + */ + +exports.version = '1.4.1' + +/** + * Send growl notification _msg_ with _options_. + * + * Options: + * + * - title Notification title + * - sticky Make the notification stick (defaults to false) + * - priority Specify an int or named key (default is 0) + * - name Application name (defaults to growlnotify) + * - image + * - path to an icon sets --iconpath + * - path to an image sets --image + * - capitalized word sets --appIcon + * - filename uses extname as --icon + * - otherwise treated as --icon + * + * Examples: + * + * growl('New email') + * growl('5 new emails', { title: 'Thunderbird' }) + * growl('Email sent', function(){ + * // ... notification sent + * }) + * + * @param {string} msg + * @param {object} options + * @param {function} fn + * @api public + */ + +function growl(msg, options, fn) { + var image + , args + , options = options || {} + , fn = fn || function(){}; + + // noop + if (!cmd) return fn(new Error('growl not supported on this platform')); + args = [cmd.pkg]; + + // image + if (image = options.image) { + switch(cmd.type) { + case 'Darwin-Growl': + var flag, ext = path.extname(image).substr(1) + flag = flag || ext == 'icns' && 'iconpath' + flag = flag || /^[A-Z]/.test(image) && 'appIcon' + flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' + flag = flag || ext && (image = ext) && 'icon' + flag = flag || 'icon' + args.push('--' + flag, image) + break; + case 'Linux': + args.push(cmd.icon + " " + image); + break; + case 'Windows': + args.push(cmd.icon + quote(image)); + break; + } + } + + // sticky + if (options.sticky) args.push(cmd.sticky); + + // priority + if (options.priority) { + var priority = options.priority + ''; + var checkindexOf = cmd.priority.range.indexOf(priority); + if (~cmd.priority.range.indexOf(priority)) { + args.push(cmd.priority, options.priority); + } + } + + // name + if (options.name && cmd.type === "Darwin-Growl") { + args.push('--name', options.name); + } + + switch(cmd.type) { + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg)); + if (options.title) args.push(quote(options.title)); + break; + case 'Darwin-NotificationCenter': + args.push(cmd.msg); + args.push(quote(msg)); + if (options.title) { + args.push(cmd.title); + args.push(quote(options.title)); + } + if (options.subtitle) { + args.push(cmd.subtitle); + args.push(quote(options.title)); + } + break; + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg)); + if (options.title) args.push(quote(options.title)); + break; + case 'Linux': + if (options.title) { + args.push(quote(options.title)); + args.push(cmd.msg); + args.push(quote(msg)); + } else { + args.push(quote(msg)); + } + break; + case 'Windows': + args.push(quote(msg)); + if (options.title) args.push(cmd.title + quote(options.title)); + break; + } + + // execute + exec(args.join(' '), fn); +}; diff --git a/node_modules/growl/package.json b/node_modules/growl/package.json new file mode 100644 index 0000000..56604b4 --- /dev/null +++ b/node_modules/growl/package.json @@ -0,0 +1,13 @@ +{ + "name": "growl", + "version": "1.6.1", + "description": "Growl unobtrusive notifications", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "main": "./lib/growl.js", + "readme": "# Growl for nodejs\n\nGrowl support for Nodejs. This is essentially a port of my [Ruby Growl Library](http://github.com/visionmedia/growl). Ubuntu/Linux support added thanks to [@niftylettuce](http://github.com/niftylettuce). \n\n## Installation\n\n### Install \n\n### Mac OS X (Darwin):\n\n Install [growlnotify(1)](http://growl.info/extras.php#growlnotify). On OS X 10.8, Notification Center is supported using [terminal-notifier](https://github.com/alloy/terminal-notifier). To install:\n \n $ sudo gem install terminal-notifier\n \n Install [npm](http://npmjs.org/) and run:\n \n $ npm install growl\n\n### Ubuntu (Linux):\n\n Install `notify-send` through the [libnotify-bin](http://packages.ubuntu.com/libnotify-bin) package:\n\n $ sudo apt-get install libnotify-bin\n\n Install [npm](http://npmjs.org/) and run:\n \n $ npm install growl\n\n### Windows:\n\n Download and install [Growl for Windows](http://www.growlforwindows.com/gfw/default.aspx)\n\n Download [growlnotify](http://www.growlforwindows.com/gfw/help/growlnotify.aspx) - **IMPORTANT :** Unpack growlnotify to a folder that is present in your path!\n\n Install [npm](http://npmjs.org/) and run:\n \n $ npm install growl\n\n## Examples\n\nCallback functions are optional\n\n var growl = require('growl')\n growl('You have mail!')\n growl('5 new messages', { sticky: true })\n growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true })\n growl('Message with title', { title: 'Title'})\n growl('Set priority', { priority: 2 })\n growl('Show Safari icon', { image: 'Safari' })\n growl('Show icon', { image: 'path/to/icon.icns' })\n growl('Show image', { image: 'path/to/my.image.png' })\n growl('Show png filesystem icon', { image: 'png' })\n growl('Show pdf filesystem icon', { image: 'article.pdf' })\n growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(err){\n // ... notified\n })\n\n## Options\n\n - title\n - notification title\n - name\n - application name\n - priority\n - priority for the notification (default is 0)\n - sticky\n - weither or not the notification should remainin until closed\n - image\n - Auto-detects the context:\n - path to an icon sets --iconpath\n - path to an image sets --image\n - capitalized word sets --appIcon\n - filename uses extname as --icon\n - otherwise treated as --icon\n \n## License \n\n(The MIT License)\n\nCopyright (c) 2009 TJ Holowaychuk \n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "_id": "growl@1.6.1", + "_from": "growl" +} diff --git a/node_modules/growl/test.js b/node_modules/growl/test.js new file mode 100644 index 0000000..cf22d90 --- /dev/null +++ b/node_modules/growl/test.js @@ -0,0 +1,20 @@ + +var growl = require('./lib/growl') + +growl('You have mail!') +growl('5 new messages', { sticky: true }) +growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true }) +growl('Message with title', { title: 'Title'}) +growl('Set priority', { priority: 2 }) +growl('Show Safari icon', { image: 'Safari' }) +growl('Show icon', { image: 'path/to/icon.icns' }) +growl('Show image', { image: 'path/to/my.image.png' }) +growl('Show png filesystem icon', { image: 'png' }) +growl('Show pdf filesystem icon', { image: 'article.pdf' }) +growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(){ + console.log('callback'); +}) +growl('Show pdf filesystem icon', { title: 'Use show()', image: 'article.pdf' }) +growl('here \' are \n some \\ characters that " need escaping', {}, function(error, stdout, stderr) { + if (error !== null) throw new Error('escaping failed:\n' + stdout + stderr); +}) diff --git a/node_modules/jsdom/.npmignore b/node_modules/jsdom/.npmignore new file mode 100644 index 0000000..6ca468a --- /dev/null +++ b/node_modules/jsdom/.npmignore @@ -0,0 +1,6 @@ +test/ +.DS_Store +.svn +.*.swp +**gmon.out +**v8.log \ No newline at end of file diff --git a/node_modules/jsdom/LICENSE.txt b/node_modules/jsdom/LICENSE.txt new file mode 100644 index 0000000..0dbd429 --- /dev/null +++ b/node_modules/jsdom/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2010 Elijah Insua + +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. diff --git a/node_modules/jsdom/README.md b/node_modules/jsdom/README.md new file mode 100644 index 0000000..853e321 --- /dev/null +++ b/node_modules/jsdom/README.md @@ -0,0 +1,282 @@ +# jsdom + +A javascript implementation of the W3C DOM. + +## Install + + npm install jsdom + +or + + git clone http://github.com/tmpvar/jsdom.git + cd jsdom + npm link + +## Human contact + +see: [mailing list][] + + [mailing list]: http://groups.google.com/group/jsdom + + + + +## Easymode + +Bootstrapping a DOM is generally a difficult process involving many error prone steps. We didn't want jsdom to fall into the same trap and that is why a new method, `jsdom.env()`, has been added in jsdom 0.2.0 which should make everyone's lives easier. + +with URL + + // Count all of the links from the nodejs build page + var jsdom = require("jsdom"); + + jsdom.env("http://nodejs.org/dist/", [ + 'http://code.jquery.com/jquery-1.5.min.js' + ], + function(errors, window) { + console.log("there have been", window.$("a").length, "nodejs releases!"); + }); + +or with raw html + + // Run some jQuery on a html fragment + var jsdom = require('jsdom'); + + jsdom.env('

jsdom\'s Homepage

', [ + 'http://code.jquery.com/jquery-1.5.min.js' + ], + function(errors, window) { + console.log("contents of a.the-link:", window.$("a.the-link").text()); + }); + + +or with a configuration object + + // Print all of the news items on hackernews + var jsdom = require('jsdom'); + + jsdom.env({ + html: 'http://news.ycombinator.com/', + scripts: [ + 'http://code.jquery.com/jquery-1.5.min.js' + ], + done: function(errors, window) { + var $ = window.$; + console.log('HN Links'); + $('td.title:not(:last) a').each(function() { + console.log(' -', $(this).text()); + }); + } + }); + +or with raw javascript source + + // Print all of the news items on hackernews + var jsdom = require('jsdom'); + var fs = require('fs'); + var jquery = fs.readFileSync("./jquery-1.6.2.min.js").toString(); + + jsdom.env({ + html: 'http://news.ycombinator.com/', + src: [ + jquery + ], + done: function(errors, window) { + var $ = window.$; + console.log('HN Links'); + $('td.title:not(:last) a').each(function() { + console.log(' -', $(this).text()); + }); + } + }); + +### How it works + `jsdom.env` is built for ease of use, which is rare in the world of the DOM! Since the web has some absolutely horrible javascript on it, as of jsdom 0.2.0 `jsdom.env` will not process external resources (scripts, images, etc). If you want to process the javascript use one of the methods below (`jsdom.jsdom` or `jsdom.jQueryify`) + + jsdom.env(html, [scripts], [config], callback) + + - `html` (**required**) + May be a url, html fragment, or file + + - `scripts` (**optional**) + May contain files or urls + + - `callback` (**required**) + Takes 2 arguments: + - `errors` : array of errors + - `window` : a brand new window + + _example:_ + + jsdom.env(html, function(`errors`, `window`) { + // free memory associated with the window + window.close(); + }); + +If you would like to specify a configuration object + + jsdom.env({ /* config */ }) + + - config.html : see `html` above + - config.scripts : see `scripts` above + - config.src : An array of javascript strings that will be evaluated against the resulting document. Similar to `scripts`, but it accepts javascript instead of paths/urls. + - config.done : see `callback` above + - config.document : + - referer : the new document will have this referer + - cookie : manually set a cookie value i.e. `'key=value; expires=Wed, Sep 21 2011 12:00:00 GMT; path=/'` + - config.features : see `Flexibility` section below. **Note**: the default feature set for jsdom.env does _not_ include fetching remote javascript and executing it. This is something that you will need to **carefully** enable yourself. + +## For the hardcore + +If you want to spawn a document/window and specify all sorts of options this is the section for you. This section covers the `jsdom.jsdom` method: + + var jsdom = require("jsdom").jsdom, + doc = jsdom(markup, level, options), + window = doc.createWindow(); + + - `markup` is an html/xml document to be parsed. You can also pass `null` or an undefined value to get a basic document with empty head and body tags. Document fragments are also supported (including `""`), and will behave as sanely as possible (eg. the resulting document will lack the `head`, `body` and `documentElement` properties if the corresponding elements aren't included). + - `level` is `null` (which means level3) by default, but you can pass another level if you'd like. + + + var jsdom = require('jsdom'), + doc = jsdom.jsdom('', jsdom.level(1, 'core')) + + - `options` see the **Flexibility** section below + +### Flexibility + +One of the goals of jsdom is to be as minimal and light as possible. This section details how +someone can change the behavior of `Document`s on the fly. These features are baked into +the `DOMImplementation` that every `Document` has, and may be tweaked in two ways: + +1. When you create a new `Document` using the jsdom builder (`require('jsdom').jsdom()`) + + var jsdom = require('jsdom').jsdom, + doc = jsdom("", null, { + features: { + FetchExternalResources : ['img'] + } + }); + + Do note, that this will only affect the document that is currently being created. All other documents +will use the defaults specified below (see: Default Features) + +2. Previous to creating any documents you can modify the defaults for all future documents + + require('jsdom').defaultDocumentFeatures = { + FetchExternalResources : ['script'], + ProcessExternalResources : false, + MutationEvents : false, + QuerySelector : false + } + + + +#### Default Features + +Default features are extremely important for jsdom as they lower the configuration requirement and present developers a set of consistent default behaviors. The following sections detail the available features, their defaults, and the values that jsdom uses. + + +`FetchExternalResources` +_Default_: ['script'] +_Allowed_: ['script', 'img', 'css', 'frame', 'link'] or false + +Enables/Disables fetching files over the filesystem/http + +`ProcessExternalResources` +_default_: ['script'] +_allowed_: ['script'] or false + +Disabling this will disable script execution (currently only javascript). + +`MutationEvents` +_default_: '2.0' +_allowed_ : '2.0' or false + +Initially enabled to be up to spec. Disable this if you do not need mutation events and want jsdom to be a bit more efficient. + +**Note**: `ProcessExternalResources` requires this to be enabled + +`QuerySelector` +_default_ : false +_allowed_ : true + +This feature is backed by [sizzle][] but currently causes problems with some libraries. Enable this if you want `document.querySelector` and friends, but be aware that many libraries feature detect for this, and it may cause you a bit of trouble. + +[sizzle]:http://sizzlejs.com/ + +# More Examples + +## Creating a document-less window + + var jsdom = require("jsdom"), + window = jsdom.createWindow(); + + console.log(window.document); + // output: undefined + +## Creating a document + var jsdom = require("jsdom"), + doc = new (jsdom.level(1, 'core').Document)(); + console.log(doc.nodeName); + // outputs: #document + +## Creating a browser-like BOM/DOM/Window + + var jsdom = require("./lib/jsdom").jsdom, + document = jsdom("hello world"), + window = document.createWindow(); + + console.log(window.document.innerHTML); + // output: 'hello world' + + console.log(window.innerWidth) + // output: 1024 + + console.log(typeof window.document.getElementsByClassName); + // outputs: function + + +## jQueryify + + var jsdom = require("jsdom"), + window = jsdom.jsdom().createWindow(); + + jsdom.jQueryify(window, 'http://code.jquery.com/jquery-1.4.2.min.js' , function() { + window.$('body').append('
Hello World, It works
'); + console.log(window.$('.testing').text()); + }); + +# Test Compliance: + + level1/core 531/531 100% + level1/html 238/238 100% + level1/svg 527/527 100% + level2/core 283/283 100% + level2/html 687/687 100% + level2/style 4/4 100% + level2/extra 4/4 100% + level3/xpath 93/93 100% + window/index 5/5 100% + window/script 8/8 100% + window/frame 14/14 100% + sizzle/index 12/15 80% + jsdom/index 63/63 100% + -------------------------------------- + TOTALS: 3/2472 failed; 99% success + TIME: 16730ms + +## Running the tests + +First you'll want to `npm install -g nodeunit` then `npm install --dev` + +Using `test/runner` you can slice and dice which tests your want to run from different levels. Usage is as follows: + + test/runner --help + Run the jsdom test suite + + Options: + -s, --suites suites that you want to run. ie: -s level1/core,1/html,html [string] + -f, --fail-fast stop on the first failed test + -h, --help show the help + -t, --tests choose the test cases to run. ie: -t jquery \ No newline at end of file diff --git a/node_modules/jsdom/benchmark/mark.js b/node_modules/jsdom/benchmark/mark.js new file mode 100644 index 0000000..b46726c --- /dev/null +++ b/node_modules/jsdom/benchmark/mark.js @@ -0,0 +1,23 @@ +// Taken from: http://ejohn.org/blog/javascript-benchmark-quality/ +module.exports = runTest(name, test, next, callback){ + var runs = [], r = 0; + setTimeout(function(){ + var start = Date.now(), diff = 0; + + for ( var n = 0; diff < 1000; n++ ) { + test(); + diff = Date.now() - start; + } + + runs.push( n ); + + if ( r++ < 4 ) + setTimeout( arguments.callee, 0 ); + else { + done(name, runs); + if ( next ) + setTimeout( next, 0 ); + } + }, 0); +} + diff --git a/node_modules/jsdom/benchmark/stats.json b/node_modules/jsdom/benchmark/stats.json new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/jsdom/changelog b/node_modules/jsdom/changelog new file mode 100644 index 0000000..fa95b94 --- /dev/null +++ b/node_modules/jsdom/changelog @@ -0,0 +1,169 @@ +0.2.15 + * Land: Fix: make sure that doctypes don't get set as the documentElement (Aria Stewart) + * Land: Add: HTTP proxy support for jsdom.env (Eugene Ware) + * Land: Add: .hostname and .pathname properties to Anchor elements to comply with WHATWG standard (Avi Deitcher) + * Land: Fix: Only decode HTML entities in text when not inside a + , Style: "style" //Special tag + , Tag: "tag" //Any tag that isn't special +} + +function Parser (handler, options) { + this._options = options ? options : { }; + if (this._options.includeLocation == undefined) { + this._options.includeLocation = false; //Do not track element position in document by default + } + + this.validateHandler(handler); + this._handler = handler; + this.reset(); +} + + //**"Static"**// + //Regular expressions used for cleaning up and parsing (stateless) + Parser._reTrim = /(^\s+|\s+$)/g; //Trim leading/trailing whitespace + Parser._reTrimComment = /(^\!--|--$)/g; //Remove comment tag markup from comment contents + Parser._reWhitespace = /\s/g; //Used to find any whitespace to split on + Parser._reTagName = /^\s*(\/?)\s*([^\s\/]+)/; //Used to find the tag name for an element + + //Regular expressions used for parsing (stateful) + Parser._reAttrib = //Find attributes in a tag + /([^=<>\"\'\s]+)\s*=\s*"([^"]*)"|([^=<>\"\'\s]+)\s*=\s*'([^']*)'|([^=<>\"\'\s]+)\s*=\s*([^'"\s]+)|([^=<>\"\'\s\/]+)/g; + Parser._reTags = /[\<\>]/g; //Find tag markers + + //**Public**// + //Methods// + //Parses a complete HTML and pushes it to the handler + Parser.prototype.parseComplete = function Parser$parseComplete (data) { + this.reset(); + this.parseChunk(data); + this.done(); + } + + //Parses a piece of an HTML document + Parser.prototype.parseChunk = function Parser$parseChunk (data) { + if (this._done) + this.handleError(new Error("Attempted to parse chunk after parsing already done")); + this._buffer += data; //FIXME: this can be a bottleneck + this.parseTags(); + } + + //Tells the parser that the HTML being parsed is complete + Parser.prototype.done = function Parser$done () { + if (this._done) + return; + this._done = true; + + //Push any unparsed text into a final element in the element list + if (this._buffer.length) { + var rawData = this._buffer; + this._buffer = ""; + var element = { + raw: rawData + , data: (this._parseState == ElementType.Text) ? rawData : rawData.replace(Parser._reTrim, "") + , type: this._parseState + }; + if (this._parseState == ElementType.Tag || this._parseState == ElementType.Script || this._parseState == ElementType.Style) + element.name = this.parseTagName(element.data); + this.parseAttribs(element); + this._elements.push(element); + } + + this.writeHandler(); + this._handler.done(); + } + + //Resets the parser to a blank state, ready to parse a new HTML document + Parser.prototype.reset = function Parser$reset () { + this._buffer = ""; + this._done = false; + this._elements = []; + this._elementsCurrent = 0; + this._current = 0; + this._next = 0; + this._location = { + row: 0 + , col: 0 + , charOffset: 0 + , inBuffer: 0 + }; + this._parseState = ElementType.Text; + this._prevTagSep = ''; + this._tagStack = []; + this._handler.reset(); + } + + //**Private**// + //Properties// + Parser.prototype._options = null; //Parser options for how to behave + Parser.prototype._handler = null; //Handler for parsed elements + Parser.prototype._buffer = null; //Buffer of unparsed data + Parser.prototype._done = false; //Flag indicating whether parsing is done + Parser.prototype._elements = null; //Array of parsed elements + Parser.prototype._elementsCurrent = 0; //Pointer to last element in _elements that has been processed + Parser.prototype._current = 0; //Position in data that has already been parsed + Parser.prototype._next = 0; //Position in data of the next tag marker (<>) + Parser.prototype._location = null; //Position tracking for elements in a stream + Parser.prototype._parseState = ElementType.Text; //Current type of element being parsed + Parser.prototype._prevTagSep = ''; //Previous tag marker found + //Stack of element types previously encountered; keeps track of when + //parsing occurs inside a script/comment/style tag + Parser.prototype._tagStack = null; + + //Methods// + //Takes an array of elements and parses any found attributes + Parser.prototype.parseTagAttribs = function Parser$parseTagAttribs (elements) { + var idxEnd = elements.length; + var idx = 0; + + while (idx < idxEnd) { + var element = elements[idx++]; + if (element.type == ElementType.Tag || element.type == ElementType.Script || element.type == ElementType.style) + this.parseAttribs(element); + } + + return(elements); + } + + //Takes an element and adds an "attribs" property for any element attributes found + Parser.prototype.parseAttribs = function Parser$parseAttribs (element) { + //Only parse attributes for tags + if (element.type != ElementType.Script && element.type != ElementType.Style && element.type != ElementType.Tag) + return; + + var tagName = element.data.split(Parser._reWhitespace, 1)[0]; + var attribRaw = element.data.substring(tagName.length); + if (attribRaw.length < 1) + return; + + var match; + Parser._reAttrib.lastIndex = 0; + while (match = Parser._reAttrib.exec(attribRaw)) { + if (element.attribs == undefined) + element.attribs = {}; + + if (typeof match[1] == "string" && match[1].length) { + element.attribs[match[1]] = match[2]; + } else if (typeof match[3] == "string" && match[3].length) { + element.attribs[match[3].toString()] = match[4].toString(); + } else if (typeof match[5] == "string" && match[5].length) { + element.attribs[match[5]] = match[6]; + } else if (typeof match[7] == "string" && match[7].length) { + element.attribs[match[7]] = match[7]; + } + } + } + + //Extracts the base tag name from the data value of an element + Parser.prototype.parseTagName = function Parser$parseTagName (data) { + if (data == null || data == "") + return(""); + var match = Parser._reTagName.exec(data); + if (!match) + return(""); + return((match[1] ? "/" : "") + match[2]); + } + + //Parses through HTML text and returns an array of found elements + //I admit, this function is rather large but splitting up had an noticeable impact on speed + Parser.prototype.parseTags = function Parser$parseTags () { + var bufferEnd = this._buffer.length - 1; + while (Parser._reTags.test(this._buffer)) { + this._next = Parser._reTags.lastIndex - 1; + var tagSep = this._buffer.charAt(this._next); //The currently found tag marker + var rawData = this._buffer.substring(this._current, this._next); //The next chunk of data to parse + + //A new element to eventually be appended to the element list + var element = { + raw: rawData + , data: (this._parseState == ElementType.Text) ? rawData : rawData.replace(Parser._reTrim, "") + , type: this._parseState + }; + + var elementName = this.parseTagName(element.data); + + //This section inspects the current tag stack and modifies the current + //element if we're actually parsing a special area (script/comment/style tag) + if (this._tagStack.length) { //We're parsing inside a script/comment/style tag + if (this._tagStack[this._tagStack.length - 1] == ElementType.Script) { //We're currently in a script tag + if (elementName.toLowerCase() == "/script") //Actually, we're no longer in a script tag, so pop it off the stack + this._tagStack.pop(); + else { //Not a closing script tag + if (element.raw.indexOf("!--") != 0) { //Make sure we're not in a comment + //All data from here to script close is now a text element + element.type = ElementType.Text; + //If the previous element is text, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Text) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep + element.raw; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + } + } + } + } + else if (this._tagStack[this._tagStack.length - 1] == ElementType.Style) { //We're currently in a style tag + if (elementName.toLowerCase() == "/style") //Actually, we're no longer in a style tag, so pop it off the stack + this._tagStack.pop(); + else { + if (element.raw.indexOf("!--") != 0) { //Make sure we're not in a comment + //All data from here to style close is now a text element + element.type = ElementType.Text; + //If the previous element is text, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Text) { + var prevElement = this._elements[this._elements.length - 1]; + if (element.raw != "") { + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep + element.raw; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + } else { //Element is empty, so just append the last tag marker found + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep; + } + } else { //The previous element was not text + if (element.raw != "") { + element.raw = element.data = element.raw; + } + } + } + } + } + else if (this._tagStack[this._tagStack.length - 1] == ElementType.Comment) { //We're currently in a comment tag + var rawLen = element.raw.length; + if (element.raw.charAt(rawLen - 2) == "-" && element.raw.charAt(rawLen - 1) == "-" && tagSep == ">") { + //Actually, we're no longer in a style tag, so pop it off the stack + this._tagStack.pop(); + //If the previous element is a comment, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Comment) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = (prevElement.raw + element.raw).replace(Parser._reTrimComment, ""); + element.raw = element.data = ""; //This causes the current element to not be added to the element list + element.type = ElementType.Text; + } + else //Previous element not a comment + element.type = ElementType.Comment; //Change the current element's type to a comment + } + else { //Still in a comment tag + element.type = ElementType.Comment; + //If the previous element is a comment, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Comment) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + element.raw + tagSep; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + element.type = ElementType.Text; + } + else + element.raw = element.data = element.raw + tagSep; + } + } + } + + //Processing of non-special tags + if (element.type == ElementType.Tag) { + element.name = elementName; + var elementNameCI = elementName.toLowerCase(); + + if (element.raw.indexOf("!--") == 0) { //This tag is really comment + element.type = ElementType.Comment; + delete element["name"]; + var rawLen = element.raw.length; + //Check if the comment is terminated in the current element + if (element.raw.charAt(rawLen - 1) == "-" && element.raw.charAt(rawLen - 2) == "-" && tagSep == ">") + element.raw = element.data = element.raw.replace(Parser._reTrimComment, ""); + else { //It's not so push the comment onto the tag stack + element.raw += tagSep; + this._tagStack.push(ElementType.Comment); + } + } + else if (element.raw.indexOf("!") == 0 || element.raw.indexOf("?") == 0) { + element.type = ElementType.Directive; + //TODO: what about CDATA? + } + else if (elementNameCI == "script") { + element.type = ElementType.Script; + //Special tag, push onto the tag stack if not terminated + if (element.data.charAt(element.data.length - 1) != "/") + this._tagStack.push(ElementType.Script); + } + else if (elementNameCI == "/script") + element.type = ElementType.Script; + else if (elementNameCI == "style") { + element.type = ElementType.Style; + //Special tag, push onto the tag stack if not terminated + if (element.data.charAt(element.data.length - 1) != "/") + this._tagStack.push(ElementType.Style); + } + else if (elementNameCI == "/style") + element.type = ElementType.Style; + if (element.name && element.name.charAt(0) == "/") + element.data = element.name; + } + + //Add all tags and non-empty text elements to the element list + if (element.raw != "" || element.type != ElementType.Text) { + if (this._options.includeLocation && !element.location) { + element.location = this.getLocation(element.type == ElementType.Tag); + } + this.parseAttribs(element); + this._elements.push(element); + //If tag self-terminates, add an explicit, separate closing tag + if ( + element.type != ElementType.Text + && + element.type != ElementType.Comment + && + element.type != ElementType.Directive + && + element.data.charAt(element.data.length - 1) == "/" + ) + this._elements.push({ + raw: "/" + element.name + , data: "/" + element.name + , name: "/" + element.name + , type: element.type + }); + } + this._parseState = (tagSep == "<") ? ElementType.Tag : ElementType.Text; + this._current = this._next + 1; + this._prevTagSep = tagSep; + } + + if (this._options.includeLocation) { + this.getLocation(); + this._location.row += this._location.inBuffer; + this._location.inBuffer = 0; + this._location.charOffset = 0; + } + this._buffer = (this._current <= bufferEnd) ? this._buffer.substring(this._current) : ""; + this._current = 0; + + this.writeHandler(); + } + + Parser.prototype.getLocation = function Parser$getLocation (startTag) { + var c, + l = this._location, + end = this._current - (startTag ? 1 : 0), + chunk = startTag && l.charOffset == 0 && this._current == 0; + + for (; l.charOffset < end; l.charOffset++) { + c = this._buffer.charAt(l.charOffset); + if (c == '\n') { + l.inBuffer++; + l.col = 0; + } else if (c != '\r') { + l.col++; + } + } + return { + line: l.row + l.inBuffer + 1 + , col: l.col + (chunk ? 0: 1) + }; + } + + //Checks the handler to make it is an object with the right "interface" + Parser.prototype.validateHandler = function Parser$validateHandler (handler) { + if ((typeof handler) != "object") + throw new Error("Handler is not an object"); + if ((typeof handler.reset) != "function") + throw new Error("Handler method 'reset' is invalid"); + if ((typeof handler.done) != "function") + throw new Error("Handler method 'done' is invalid"); + if ((typeof handler.writeTag) != "function") + throw new Error("Handler method 'writeTag' is invalid"); + if ((typeof handler.writeText) != "function") + throw new Error("Handler method 'writeText' is invalid"); + if ((typeof handler.writeComment) != "function") + throw new Error("Handler method 'writeComment' is invalid"); + if ((typeof handler.writeDirective) != "function") + throw new Error("Handler method 'writeDirective' is invalid"); + } + + //Writes parsed elements out to the handler + Parser.prototype.writeHandler = function Parser$writeHandler (forceFlush) { + forceFlush = !!forceFlush; + if (this._tagStack.length && !forceFlush) + return; + while (this._elements.length) { + var element = this._elements.shift(); + switch (element.type) { + case ElementType.Comment: + this._handler.writeComment(element); + break; + case ElementType.Directive: + this._handler.writeDirective(element); + break; + case ElementType.Text: + this._handler.writeText(element); + break; + default: + this._handler.writeTag(element); + break; + } + } + } + + Parser.prototype.handleError = function Parser$handleError (error) { + if ((typeof this._handler.error) == "function") + this._handler.error(error); + else + throw error; + } + +//TODO: make this a trully streamable handler +function RssHandler (callback) { + RssHandler.super_.call(this, callback, { ignoreWhitespace: true, verbose: false, enforceEmptyTags: false }); +} +inherits(RssHandler, DefaultHandler); + + RssHandler.prototype.done = function RssHandler$done () { + var feed = { }; + var feedRoot; + + var found = DomUtils.getElementsByTagName(function (value) { return(value == "rss" || value == "feed"); }, this.dom, false); + if (found.length) { + feedRoot = found[0]; + } + if (feedRoot) { + if (feedRoot.name == "rss") { + feed.type = "rss"; + feedRoot = feedRoot.children[0]; // + feed.id = ""; + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("description", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("lastBuildDate", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("managingEditor", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("item", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("guid", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("description", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("pubDate", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } else { + feed.type = "atom"; + try { + feed.id = DomUtils.getElementsByTagName("id", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].attribs.href; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("subtitle", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("updated", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("email", feedRoot.children, true)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("entry", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("id", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].attribs.href; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("summary", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("updated", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } + + this.dom = feed; + } + RssHandler.super_.prototype.done.call(this); + } + +/////////////////////////////////////////////////// + +function DefaultHandler (callback, options) { + this.reset(); + this._options = options ? options : { }; + if (this._options.ignoreWhitespace == undefined) + this._options.ignoreWhitespace = false; //Keep whitespace-only text nodes + if (this._options.verbose == undefined) + this._options.verbose = true; //Keep data property for tags and raw property for all + if (this._options.enforceEmptyTags == undefined) + this._options.enforceEmptyTags = true; //Don't allow children for HTML tags defined as empty in spec + if ((typeof callback) == "function") + this._callback = callback; +} + + //**"Static"**// + //HTML Tags that shouldn't contain child nodes + DefaultHandler._emptyTags = { + area: 1 + , base: 1 + , basefont: 1 + , br: 1 + , col: 1 + , frame: 1 + , hr: 1 + , img: 1 + , input: 1 + , isindex: 1 + , link: 1 + , meta: 1 + , param: 1 + , embed: 1 + } + //Regex to detect whitespace only text nodes + DefaultHandler.reWhitespace = /^\s*$/; + + //**Public**// + //Properties// + DefaultHandler.prototype.dom = null; //The hierarchical object containing the parsed HTML + //Methods// + //Resets the handler back to starting state + DefaultHandler.prototype.reset = function DefaultHandler$reset() { + this.dom = []; + this._done = false; + this._tagStack = []; + this._tagStack.last = function DefaultHandler$_tagStack$last () { + return(this.length ? this[this.length - 1] : null); + } + } + //Signals the handler that parsing is done + DefaultHandler.prototype.done = function DefaultHandler$done () { + this._done = true; + this.handleCallback(null); + } + DefaultHandler.prototype.writeTag = function DefaultHandler$writeTag (element) { + this.handleElement(element); + } + DefaultHandler.prototype.writeText = function DefaultHandler$writeText (element) { + if (this._options.ignoreWhitespace) + if (DefaultHandler.reWhitespace.test(element.data)) + return; + this.handleElement(element); + } + DefaultHandler.prototype.writeComment = function DefaultHandler$writeComment (element) { + this.handleElement(element); + } + DefaultHandler.prototype.writeDirective = function DefaultHandler$writeDirective (element) { + this.handleElement(element); + } + DefaultHandler.prototype.error = function DefaultHandler$error (error) { + this.handleCallback(error); + } + + //**Private**// + //Properties// + DefaultHandler.prototype._options = null; //Handler options for how to behave + DefaultHandler.prototype._callback = null; //Callback to respond to when parsing done + DefaultHandler.prototype._done = false; //Flag indicating whether handler has been notified of parsing completed + DefaultHandler.prototype._tagStack = null; //List of parents to the currently element being processed + //Methods// + DefaultHandler.prototype.handleCallback = function DefaultHandler$handleCallback (error) { + if ((typeof this._callback) != "function") + if (error) + throw error; + else + return; + this._callback(error, this.dom); + } + + DefaultHandler.prototype.isEmptyTag = function(element) { + var name = element.name.toLowerCase(); + if (name.charAt(0) == '/') { + name = name.substring(1); + } + return this._options.enforceEmptyTags && !!DefaultHandler._emptyTags[name]; + }; + + DefaultHandler.prototype.handleElement = function DefaultHandler$handleElement (element) { + if (this._done) + this.handleCallback(new Error("Writing to the handler after done() called is not allowed without a reset()")); + if (!this._options.verbose) { +// element.raw = null; //FIXME: Not clean + //FIXME: Serious performance problem using delete + delete element.raw; + if (element.type == "tag" || element.type == "script" || element.type == "style") + delete element.data; + } + if (!this._tagStack.last()) { //There are no parent elements + //If the element can be a container, add it to the tag stack and the top level list + if (element.type != ElementType.Text && element.type != ElementType.Comment && element.type != ElementType.Directive) { + if (element.name.charAt(0) != "/") { //Ignore closing tags that obviously don't have an opening tag + this.dom.push(element); + if (!this.isEmptyTag(element)) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(element); + } + } + } + else //Otherwise just add to the top level list + this.dom.push(element); + } + else { //There are parent elements + //If the element can be a container, add it as a child of the element + //on top of the tag stack and then add it to the tag stack + if (element.type != ElementType.Text && element.type != ElementType.Comment && element.type != ElementType.Directive) { + if (element.name.charAt(0) == "/") { + //This is a closing tag, scan the tagStack to find the matching opening tag + //and pop the stack up to the opening tag's parent + var baseName = element.name.substring(1); + if (!this.isEmptyTag(element)) { + var pos = this._tagStack.length - 1; + while (pos > -1 && this._tagStack[pos--].name != baseName) { } + if (pos > -1 || this._tagStack[0].name == baseName) + while (pos < this._tagStack.length - 1) + this._tagStack.pop(); + } + } + else { //This is not a closing tag + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(element); + if (!this.isEmptyTag(element)) //Don't add tags to the tag stack that can't have children + this._tagStack.push(element); + } + } + else { //This is not a container element + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(element); + } + } + } + + var DomUtils = { + testElement: function DomUtils$testElement (options, element) { + if (!element) { + return false; + } + + for (var key in options) { + if (key == "tag_name") { + if (element.type != "tag" && element.type != "script" && element.type != "style") { + return false; + } + if (!options["tag_name"](element.name)) { + return false; + } + } else if (key == "tag_type") { + if (!options["tag_type"](element.type)) { + return false; + } + } else if (key == "tag_contains") { + if (element.type != "text" && element.type != "comment" && element.type != "directive") { + return false; + } + if (!options["tag_contains"](element.data)) { + return false; + } + } else { + if (!element.attribs || !options[key](element.attribs[key])) { + return false; + } + } + } + + return true; + } + + , getElements: function DomUtils$getElements (options, currentElement, recurse, limit) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + limit = isNaN(parseInt(limit)) ? -1 : parseInt(limit); + + if (!currentElement) { + return([]); + } + + var found = []; + var elementList; + + function getTest (checkVal) { + return(function (value) { return(value == checkVal); }); + } + for (var key in options) { + if ((typeof options[key]) != "function") { + options[key] = getTest(options[key]); + } + } + + if (DomUtils.testElement(options, currentElement)) { + found.push(currentElement); + } + + if (limit >= 0 && found.length >= limit) { + return(found); + } + + if (recurse && currentElement.children) { + elementList = currentElement.children; + } else if (currentElement instanceof Array) { + elementList = currentElement; + } else { + return(found); + } + + for (var i = 0; i < elementList.length; i++) { + found = found.concat(DomUtils.getElements(options, elementList[i], recurse, limit)); + if (limit >= 0 && found.length >= limit) { + break; + } + } + + return(found); + } + + , getElementById: function DomUtils$getElementById (id, currentElement, recurse) { + var result = DomUtils.getElements({ id: id }, currentElement, recurse, 1); + return(result.length ? result[0] : null); + } + + , getElementsByTagName: function DomUtils$getElementsByTagName (name, currentElement, recurse, limit) { + return(DomUtils.getElements({ tag_name: name }, currentElement, recurse, limit)); + } + + , getElementsByTagType: function DomUtils$getElementsByTagType (type, currentElement, recurse, limit) { + return(DomUtils.getElements({ tag_type: type }, currentElement, recurse, limit)); + } + } + + function inherits (ctor, superCtor) { + var tempCtor = function(){}; + tempCtor.prototype = superCtor.prototype; + ctor.super_ = superCtor; + ctor.prototype = new tempCtor(); + ctor.prototype.constructor = ctor; + } + +exports.Parser = Parser; + +exports.DefaultHandler = DefaultHandler; + +exports.RssHandler = RssHandler; + +exports.ElementType = ElementType; + +exports.DomUtils = DomUtils; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/lib/htmlparser.min.js b/node_modules/jsdom/node_modules/htmlparser/lib/htmlparser.min.js new file mode 100644 index 0000000..c1281c5 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/lib/htmlparser.min.js @@ -0,0 +1,22 @@ +/*********************************************** +Copyright 2010, 2011, Chris Winberry . All rights reserved. +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. +***********************************************/ +/* v1.7.6 */ +(function(){function e(a,c){this._options=c?c:{};void 0==this._options.includeLocation&&(this._options.includeLocation=!1);this.validateHandler(a);this._handler=a;this.reset()}function j(a){j.super_.call(this,a,{ignoreWhitespace:!0,verbose:!1,enforceEmptyTags:!1})}function g(a,c){this.reset();this._options=c?c:{};void 0==this._options.ignoreWhitespace&&(this._options.ignoreWhitespace=!1);void 0==this._options.verbose&&(this._options.verbose=!0);void 0==this._options.enforceEmptyTags&&(this._options.enforceEmptyTags= !0);"function"==typeof a&&(this._callback=a)}if(!("function"==typeof require&&"object"==typeof exports&&"object"==typeof module&&"string"==typeof __filename&&"string"==typeof __dirname)){if(this.Tautologistics){if(this.Tautologistics.NodeHtmlParser)return}else this.Tautologistics={};this.Tautologistics.NodeHtmlParser={};exports=this.Tautologistics.NodeHtmlParser}var d={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag"};e._reTrim=/(^\s+|\s+$)/g;e._reTrimComment= /(^\!--|--$)/g;e._reWhitespace=/\s/g;e._reTagName=/^\s*(\/?)\s*([^\s\/]+)/;e._reAttrib=/([^=<>\"\'\s]+)\s*=\s*"([^"]*)"|([^=<>\"\'\s]+)\s*=\s*'([^']*)'|([^=<>\"\'\s]+)\s*=\s*([^'"\s]+)|([^=<>\"\'\s\/]+)/g;e._reTags=/[\<\>]/g;e.prototype.parseComplete=function(a){this.reset();this.parseChunk(a);this.done()};e.prototype.parseChunk=function(a){this._done&&this.handleError(Error("Attempted to parse chunk after parsing already done"));this._buffer+=a;this.parseTags()};e.prototype.done=function(){if(!this._done){this._done= !0;if(this._buffer.length){var a=this._buffer;this._buffer="";a={raw:a,data:this._parseState==d.Text?a:a.replace(e._reTrim,""),type:this._parseState};if(this._parseState==d.Tag||this._parseState==d.Script||this._parseState==d.Style)a.name=this.parseTagName(a.data);this.parseAttribs(a);this._elements.push(a)}this.writeHandler();this._handler.done()}};e.prototype.reset=function(){this._buffer="";this._done=!1;this._elements=[];this._next=this._current=this._elementsCurrent=0;this._location={row:0,col:0, charOffset:0,inBuffer:0};this._parseState=d.Text;this._prevTagSep="";this._tagStack=[];this._handler.reset()};e.prototype._options=null;e.prototype._handler=null;e.prototype._buffer=null;e.prototype._done=!1;e.prototype._elements=null;e.prototype._elementsCurrent=0;e.prototype._current=0;e.prototype._next=0;e.prototype._location=null;e.prototype._parseState=d.Text;e.prototype._prevTagSep="";e.prototype._tagStack=null;e.prototype.parseTagAttribs=function(a){for(var c=a.length,b=0;bc.length)){var b;for(e._reAttrib.lastIndex=0;b=e._reAttrib.exec(c);)void 0==a.attribs&&(a.attribs={}),"string"==typeof b[1]&&b[1].length?a.attribs[b[1]]=b[2]:"string"==typeof b[3]&&b[3].length?a.attribs[b[3].toString()]=b[4].toString():"string"==typeof b[5]&& b[5].length?a.attribs[b[5]]=b[6]:"string"==typeof b[7]&&b[7].length&&(a.attribs[b[7]]=b[7])}}};e.prototype.parseTagName=function(a){if(null==a||""==a)return"";a=e._reTagName.exec(a);return!a?"":(a[1]?"/":"")+a[2]};e.prototype.parseTags=function(){for(var a=this._buffer.length-1;e._reTags.test(this._buffer);){this._next=e._reTags.lastIndex-1;var c=this._buffer.charAt(this._next),b=this._buffer.substring(this._current,this._next),b={raw:b,data:this._parseState==d.Text?b:b.replace(e._reTrim,""),type:this._parseState}, f=this.parseTagName(b.data);if(this._tagStack.length)if(this._tagStack[this._tagStack.length-1]==d.Script)if("/script"==f.toLowerCase())this._tagStack.pop();else{if(0!=b.raw.indexOf("!--")&&(b.type=d.Text,this._elements.length&&this._elements[this._elements.length-1].type==d.Text)){var h=this._elements[this._elements.length-1];h.raw=h.data=h.raw+this._prevTagSep+b.raw;b.raw=b.data=""}}else this._tagStack[this._tagStack.length-1]==d.Style?"/style"==f.toLowerCase()?this._tagStack.pop():0!=b.raw.indexOf("!--")&& (b.type=d.Text,this._elements.length&&this._elements[this._elements.length-1].type==d.Text?(h=this._elements[this._elements.length-1],""!=b.raw?(h.raw=h.data=h.raw+this._prevTagSep+b.raw,b.raw=b.data=""):h.raw=h.data=h.raw+this._prevTagSep):""!=b.raw&&(b.raw=b.data=b.raw)):this._tagStack[this._tagStack.length-1]==d.Comment&&(h=b.raw.length,"-"==b.raw.charAt(h-2)&&"-"==b.raw.charAt(h-1)&&">"==c?(this._tagStack.pop(),this._elements.length&&this._elements[this._elements.length-1].type==d.Comment?(h= this._elements[this._elements.length-1],h.raw=h.data=(h.raw+b.raw).replace(e._reTrimComment,""),b.raw=b.data="",b.type=d.Text):b.type=d.Comment):(b.type=d.Comment,this._elements.length&&this._elements[this._elements.length-1].type==d.Comment?(h=this._elements[this._elements.length-1],h.raw=h.data=h.raw+b.raw+c,b.raw=b.data="",b.type=d.Text):b.raw=b.data=b.raw+c));if(b.type==d.Tag&&(b.name=f,f=f.toLowerCase(),0==b.raw.indexOf("!--")?(b.type=d.Comment,delete b.name,h=b.raw.length,"-"==b.raw.charAt(h- 1)&&"-"==b.raw.charAt(h-2)&&">"==c?b.raw=b.data=b.raw.replace(e._reTrimComment,""):(b.raw+=c,this._tagStack.push(d.Comment))):0==b.raw.indexOf("!")||0==b.raw.indexOf("?")?b.type=d.Directive:"script"==f?(b.type=d.Script,"/"!=b.data.charAt(b.data.length-1)&&this._tagStack.push(d.Script)):"/script"==f?b.type=d.Script:"style"==f?(b.type=d.Style,"/"!=b.data.charAt(b.data.length-1)&&this._tagStack.push(d.Style)):"/style"==f&&(b.type=d.Style),b.name&&"/"==b.name.charAt(0)))b.data=b.name;if(""!=b.raw||b.type!= d.Text)this._options.includeLocation&&!b.location&&(b.location=this.getLocation(b.type==d.Tag)),this.parseAttribs(b),this._elements.push(b),b.type!=d.Text&&b.type!=d.Comment&&b.type!=d.Directive&&"/"==b.data.charAt(b.data.length-1)&&this._elements.push({raw:"/"+b.name,data:"/"+b.name,name:"/"+b.name,type:b.type});this._parseState="<"==c?d.Tag:d.Text;this._current=this._next+1;this._prevTagSep=c}this._options.includeLocation&&(this.getLocation(),this._location.row+=this._location.inBuffer,this._location.inBuffer= 0,this._location.charOffset=0);this._buffer=this._current<=a?this._buffer.substring(this._current):"";this._current=0;this.writeHandler()};e.prototype.getLocation=function(a){for(var c=this._location,b=this._current-(a?1:0),d=a&&0==c.charOffset&&0==this._current;c.charOffset=d)return g;if(b&&c.children)c= c.children;else if(!(c instanceof Array))return g;for(i=0;i=d);i++);return g},getElementById:function(a,c,b){a=f.getElements({id:a},c,b,1);return a.length?a[0]:null},getElementsByTagName:function(a,c,b,d){return f.getElements({tag_name:a},c,b,d)},getElementsByTagType:function(a,c,b,d){return f.getElements({tag_type:a},c,b,d)}};exports.Parser=e;exports.DefaultHandler=g;exports.RssHandler=j;exports.ElementType=d;exports.DomUtils=f})(); \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.js b/node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.js new file mode 100644 index 0000000..1fc03ea --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.js @@ -0,0 +1,6 @@ +var htmlparser = require("./htmlparser"); +exports.Parser = htmlparser.Parser; +exports.DefaultHandler = htmlparser.DefaultHandler; +exports.RssHandler = htmlparser.RssHandler; +exports.ElementType = htmlparser.ElementType; +exports.DomUtils = htmlparser.DomUtils; diff --git a/node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.min.js b/node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.min.js new file mode 100644 index 0000000..27d5eea --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/lib/node-htmlparser.min.js @@ -0,0 +1,6 @@ +var htmlparser = require("./htmlparser.min"); +exports.Parser = htmlparser.Parser; +exports.DefaultHandler = htmlparser.DefaultHandler; +exports.RssHandler = htmlparser.RssHandler; +exports.ElementType = htmlparser.ElementType; +exports.DomUtils = htmlparser.DomUtils; diff --git a/node_modules/jsdom/node_modules/htmlparser/libxmljs.node b/node_modules/jsdom/node_modules/htmlparser/libxmljs.node new file mode 100644 index 0000000000000000000000000000000000000000..07e08c87c96e0c9a735bbb71e757fb3df8574f77 GIT binary patch literal 102420 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 literal 0 HcmV?d00001 diff --git a/node_modules/jsdom/node_modules/htmlparser/new/a b/node_modules/jsdom/node_modules/htmlparser/new/a new file mode 100644 index 0000000..4506b37 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/new/a @@ -0,0 +1,6 @@ +[ +{"type":"tag","name":"script","name_raw":"script","raw":"script language='javascript'"}, +{"type":"attr","name":"langauge","name_raw":"language","value":"javascript"}, +{"type":"text","data":"\nvar foo = 'xxx';\n"}, +{"type":"tag","name":"/script","name_raw":"/script","raw":"/script"} +] diff --git a/node_modules/jsdom/node_modules/htmlparser/new/b b/node_modules/jsdom/node_modules/htmlparser/new/b new file mode 100644 index 0000000..759c80f --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/new/b @@ -0,0 +1,6 @@ +[ +{"type":"tag","name":"script","name_raw":"script","raw":"script language='javascript'"}, +{"type":"attr","name":"language","name_raw":"language","value":"javascript"}, +{"type":"text","data":"\nvar foo = 'xxx';\n"}, +{"type":"tag","name":"/script","name_raw":"/script","raw":"/script"} +] diff --git a/node_modules/jsdom/node_modules/htmlparser/new/compat.js b/node_modules/jsdom/node_modules/htmlparser/new/compat.js new file mode 100644 index 0000000..eb1f4e7 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/new/compat.js @@ -0,0 +1,954 @@ +var htmlparser_old = require('../lib/htmlparser'); +var htmlparser_new = require('./htmlparser'); + +var tests = { + + 'plain text': { + data: ['This is the text'] + , expected: [{ type: 'text', data: 'This is the text' }] + } + + , 'split text': { + data: ['This is', ' the text'] + , expected: [{ type: 'text', data: 'This is the text' }] + } + + , 'simple tag': { + data: ['
'] + , expected: [{ type: 'tag', name: 'div', raw: 'div' }] + } + + , 'simple comment': { + data: [''] + , expected: [{ type: 'comment', data: ' content ' }] + } + + , 'simple cdata': { + data: [''] + , expected: [{ type: 'cdata', data: ' content ' }] + } + + , 'split simple tag #1': { + data: ['<', 'div>'] + , expected: [{ type: 'tag', name: 'div', raw: 'div' }] + } + + , 'split simple tag #2': { + data: [''] + , expected: [{ type: 'tag', name: 'div', raw: 'div' }] + } + + , 'split simple tag #3': { + data: [''] + , expected: [{ type: 'tag', name: 'div', raw: 'div' }] + } + + , 'text before tag': { + data: ['xxx
'] + , expected: [ + { type: 'text', data: 'xxx'}, + { type: 'tag', name: 'div', raw: 'div' } + ] + } + + , 'text after tag': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div' }, + { type: 'text', data: 'xxx'} + ] + } + + , 'text inside tag': { + data: ['
xxx
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div' }, + { type: 'text', data: 'xxx'}, + { type: 'tag', name: '/div', raw: '/div' } + ] + } + + , 'attribute with single quotes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=\'1\'' }, + { type: 'attr', name:'a', data: '1'} + ] + } + + , 'attribute with double quotes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a="1"' }, + { type: 'attr', name:'a', data: '1'} + ] + } + + , 'attribute with no quotes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=1' }, + { type: 'attr', name:'a', data: '1'} + ] + } + + , 'attribute with no value': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div wierd' }, + { type: 'attr', name:'wierd', data: null} + ] + } + + , 'attribute with no value, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div wierd' }, + { type: 'attr', name:'wierd', data: null}, + { type: 'text', data: 'xxx' } + ] + } + + , 'tag with multiple attributes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a="1" b="2"' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'} + ] + } + + , 'tag with multiple attributes, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a="1" b="2"' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'text', data: 'xxx' } + ] + } + + , 'tag with mixed attributes #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=1 b=\'2\' c="3"' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'} + ] + } + + , 'tag with mixed attributes #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=1 b="2" c=\'3\'' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'} + ] + } + + , 'tag with mixed attributes #3': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=\'1\' b=2 c="3"' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'} + ] + } + + , 'tag with mixed attributes #4': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=\'1\' b="2" c=3' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'} + ] + } + + , 'tag with mixed attributes #5': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a="1" b=2 c=\'3\'' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'} + ] + } + + , 'tag with mixed attributes #6': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a="1" b=\'2\' c="3"' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'} + ] + } + + , 'tag with mixed attributes, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=1 b=\'2\' c="3"' }, + { type: 'attr', name:'a', data: '1'}, + { type: 'attr', name:'b', data: '2'}, + { type: 'attr', name:'c', data: '3'}, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'self closing tag, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', raw: null }, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag with spaces #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div /' }, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'self closing tag with spaces #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div/ ' }, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'self closing tag with spaces #3': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div / ' }, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'self closing tag with spaces, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div / ' }, + { type: 'tag', name: '/div', raw: null }, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag with attribute': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=b /' }, + { type: 'attr', name:'a', data: 'b'}, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'self closing tag with attribute, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a=b /' }, + { type: 'attr', name:'a', data: 'b'}, + { type: 'tag', name: '/div', raw: null }, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag split #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'self closing tag split #2': { + data: [''] + , expected: [ + { type: 'tag', name: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', raw: null } + ] + } + + , 'attribute missing close quote': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div a="1>'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'split attribute #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'split attribute #3': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'split attribute #4': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'split attribute #5': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'split attribute #6': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'attribute split from tag #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'attribute split from tag #2': { + data: [''] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', data: 'yyy'} + ] + } + + , 'text before complex tag': { + data: ['xxx
'] + , expected: [ + { type: 'text', data: 'xxx' }, + { type: 'tag', name: 'div', raw: 'div yyy="123"'}, + { type: 'attr', name: 'yyy', data: '123' } + ] + } + + , 'text after complex tag': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div yyy="123"'}, + { type: 'attr', name: 'yyy', data: '123' }, + { type: 'text', data: 'xxx' } + ] + } + + , 'text inside complex tag': { + data: ['
xxx
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div yyy="123"'}, + { type: 'attr', name: 'yyy', data: '123' }, + { type: 'text', data: 'xxx' }, + { type: 'tag', name: '/div', raw: '/div'} + ] + } + + , 'nested tags': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div'}, + { type: 'tag', name: 'span', raw: 'span'}, + { type: 'tag', name: '/span', raw: '/span'}, + { type: 'tag', name: '/div', raw: '/div'} + ] + } + + , 'nested tags with attributes': { + data: ['
xxx
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div aaa="bbb"'}, + { type: 'attr', name: 'aaa', data: 'bbb' }, + { type: 'tag', name: 'span', raw: 'span 123=\'456\''}, + { type: 'attr', name: '123', data: '456' }, + { type: 'text', data: 'xxx' }, + { type: 'tag', name: '/span', raw: '/span'}, + { type: 'tag', name: '/div', raw: '/div'} + ] + } + + , 'comment inside tag': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div'}, + { type: 'comment', data: ' comment text '}, + { type: 'tag', name: '/div', raw: '/div'} + ] + } + + , 'cdata inside tag': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div'}, + { type: 'cdata', data: ' CData content '}, + { type: 'tag', name: '/div', raw: '/div'} + ] + } + + , 'html inside comment': { + data: [''] + , expected: [{ type: 'comment', data: '
foo
'}] + } + + , 'html inside cdata': { + data: ['foo
]]>'] + , expected: [{ type: 'cdata', data: '
foo
'}] + } + + , 'quotes in attribute #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx=\'a"b\''}, + { type: 'attr', name: 'xxx', data: 'a"b' } + ] + } + + , 'quotes in attribute #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="a\'b"'}, + { type: 'attr', name: 'xxx', data: 'a\'b' } + ] + } + + , 'brackets in attribute': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', raw: 'div xxx="
"'}, + { type: 'attr', name: 'xxx', data: '
' } + ] + } + + , 'split comment #1': { + data: ['<','!-- comment text -->xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #2': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #3': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #4': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #5': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #6': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #7': { + data: ['"] + , expected: [ + { type: 'comment', data: "\ncomment text\n" } + ] + } + + , 'cdata comment': { + data: [""] + , expected: [ + { type: 'cdata', data: "\nCData content\n" } + ] + } + + , 'multiline attribute #1': { + data: ["
"] + , expected: [ + { type: 'tag', name: 'div', raw: "div id='\nxxx\nyyy\n'" }, + { type: 'attr', name: 'id', data: "\nxxx\nyyy\n" } + ] + } + + , 'multiline attribute #2': { + data: ["
"] + , expected: [ + { type: 'tag', name: 'div', raw: "div id=\"\nxxx\nyyy\n\"" }, + { type: 'attr', name: 'id', data: "\nxxx\nyyy\n" } + ] + } + + , 'tags in script tag code': { + data: [""] + , expected: [ + { type: 'tag', name: 'script', raw: "script language='javascript'" }, + { type: 'attr', name: 'language', data: 'javascript' }, + { type: 'text', data: "\nvar foo = 'xxx';\n" }, + { type: 'tag', name: '/script', raw: "/script" }, + ] + } + + , 'closing script tag in script tag code': { + data: ["';\n"] + , expected: [ + { type: 'tag', name: 'script', raw: "script language='javascript'" }, + { type: 'attr', name: 'language', data: 'javascript' }, + { type: 'text', data: "\nvar foo = '" }, + { type: 'tag', name: '/script', raw: "/script" }, + { type: 'text', data: "';\n" }, + { type: 'tag', name: '/script', raw: "/script" } + ] + } + + , 'comment in script tag code': { + data: [""] + , expected: [ + { type: 'tag', name: 'script', raw: "script language='javascript'" }, + { type: 'attr', name: 'language', data: 'javascript' }, + { type: 'text', data: "\nvar foo = '';\n" }, + { type: 'tag', name: '/script', raw: "/script" }, + ] + } + + , 'cdata in script tag code': { + data: [""] + , expected: [ + { type: 'tag', name: 'script', raw: "script language='javascript'" }, + { type: 'attr', name: 'language', data: 'javascript' }, + { type: 'text', data: "\nvar foo = '';\n" }, + { type: 'tag', name: '/script', raw: "/script" }, + ] + } + + , 'commented script tag code': { + data: [""] + , expected: [ + { type: 'tag', name: 'script', raw: "script language='javascript'" }, + { type: 'attr', name: 'language', data: 'javascript' }, + { type: 'text', data: "\n\n" }, + { type: 'tag', name: '/script', raw: "/script" }, + ] + } + + , 'cdata in script tag': { + data: [""] + , expected: [ + { type: 'tag', name: 'script', raw: "script language='javascript'" }, + { type: 'attr', name: 'language', data: 'javascript' }, + { type: 'text', data: "\nxxx';\n]]>\n" }, + { type: 'tag', name: '/script', raw: "/script" }, + ] + } + +}; + +function runTests (permutator) { + var callback = function handlerCallback (err) { + if (err) { + console.log('Handler error', err); + } + } + var handler = new htmlparser_new.HtmlHandler(callback); + var parser = new htmlparser_new.Parser(handler); + + var passed = 0; + var failed = 0; + + console.time('Tests'); + for (var testName in tests) { + var test = permutator ? permutator(tests[testName]) : tests[testName]; + process.stdout.write('[TEST] ' + testName + ' : '); + parser.reset(); + for (var i = 0, len = test.data.length; i < len; i++) { + parser.parseChunk(test.data[i]); + } + parser.done(); + var expected = JSON.stringify(test.expected); + var result = JSON.stringify(parser.state.output); + if (expected !== result) { + failed++; + process.stdout.write("FAIL\n"); + console.log(' [EXPECTED]', expected); + console.log(' [ RESULT ]', result); + } else { + passed++; + process.stdout.write("Ok\n"); + } + } + console.timeEnd('Tests'); + console.log('Passed tests: ' + passed + '/' + (passed + failed) + ' (' + Math.round(passed / (passed + failed) * 100) + '%)'); +} + +runTests(); +runTests(function (test) { + test.data = test.data.join('').split(''); + return test; +}); + +function handlerCallback (err, dom) { + console.log(err || dom); +} + +var handlerOld = new htmlparser_old.DefaultHandler(handlerCallback); +var parserOld = new htmlparser_old.Parser(handlerOld); + +var handlerNew = new htmlparser_new.HtmlHandler(null, handlerCallback); +var parserNew = new htmlparser_new.Parser(handlerNew); +parserNew.parseComplete(''); + diff --git a/node_modules/jsdom/node_modules/htmlparser/new/htmlparser.js b/node_modules/jsdom/node_modules/htmlparser/new/htmlparser.js new file mode 100644 index 0000000..6b9bfe9 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/new/htmlparser.js @@ -0,0 +1,645 @@ +(function () { + +function runningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!runningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + else if (this.Tautologistics.NodeHtmlParser) + return; //NodeHtmlParser already defined! + this.Tautologistics.NodeHtmlParser = {}; + exports = this.Tautologistics.NodeHtmlParser; +} + +var Mode = { + Text: 'text', + Tag: 'tag', + Attr: 'attr', + CData: 'cdata', + Comment: 'comment' +}; + +var re_parseText_scriptClose = /<\s*\/\s*script/ig; +function parseText (state) { + var foundPos; + if (state.isScript) { + re_parseText_scriptClose.lastIndex = state.pos; + foundPos = re_parseText_scriptClose.exec(state.data); + foundPos = (foundPos) ? + foundPos.index + : + -1 + ; + } else { + foundPos = state.data.indexOf('<', state.pos); + } + var text = (foundPos === -1) ? state.data.substring(state.pos, state.data.length) : state.data.substring(state.pos, foundPos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + if (state.isScript) { + state.needData = true; + return; + } + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substring(state.pos, state.data.length)); + state.pos = state.data.length; + } else { + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + if (text !== '') { + state.output.push({ type: Mode.Text, data: text }); + } + state.pos = foundPos + 1; + state.mode = Mode.Tag; + } +} + +var re_parseTag = /\s*(\/?)\s*([^\s>\/]+)(\s*)(>?)/g; +function parseTag (state) { + re_parseTag.lastIndex = state.pos; + var match = re_parseTag.exec(state.data); + if (match) { + if (!match[1] && match[2].substr(0, 3) === '!--') { + state.mode = Mode.Comment; + state.pos += 3; + return; + } + if (!match[1] && match[2].substr(0, 8) === '![CDATA[') { + state.mode = Mode.CData; + state.pos += 8; + return; + } + if (!state.done && (state.pos + match[0].length) === state.data.length) { + //We're at the and of the data, might be incomplete + state.needData = true; + return; + } + var raw; + if (match[4] === '>') { + state.mode = Mode.Text; + raw = match[0].substr(0, match[0].length - 1); + } else { + state.mode = Mode.Attr; + raw = match[0]; + } + state.pos += match[0].length; + var tag = { type: Mode.Tag, name: match[1] + match[2], raw: raw }; + if (state.mode === Mode.Attr) { + state.lastTag = tag; + } + if (tag.name.toLowerCase() === 'script') { + state.isScript = true; + } else if (tag.name.toLowerCase() === '/script') { + state.isScript = false; + } + state.output.push(tag); + } else { + //TODO: end of tag? + //TODO: push to pending? + state.needData = true; + } +} + +var re_parseAttr_findName = /\s*([^=<>\s'"\/]+)\s*/g; +function parseAttr_findName (state) { + re_parseAttr_findName.lastIndex = state.pos; + var match = re_parseAttr_findName.exec(state.data); + if (!match) { + return null; + } + if (state.pos + match[0].length !== re_parseAttr_findName.lastIndex) { + return null; + } + return { + match: match[0] + , name: match[1] + }; +} +var re_parseAttr_findValue = /\s*=\s*(?:'([^']*)'|"([^"]*)"|([^'"\s\/>]+))\s*/g; +var re_parseAttr_findValue_last = /\s*=\s*['"]?(.*)$/g; +function parseAttr_findValue (state) { + re_parseAttr_findValue.lastIndex = state.pos; + var match = re_parseAttr_findValue.exec(state.data); + if (!match) { + if (!state.done) { + return null; + } + re_parseAttr_findValue_last.lastIndex = state.pos; + match = re_parseAttr_findValue_last.exec(state.data); + if (!match) { + return null; + } + return { + match: match[0] + , value: (match[1] !== '') ? match[1] : null + }; + } + if (state.pos + match[0].length !== re_parseAttr_findValue.lastIndex) { + return null; + } + return { + match: match[0] + , value: match[1] || match[2] || match[3] + }; +} +var re_parseAttr_splitValue = /\s*=\s*['"]?/g; +var re_parseAttr_selfClose = /(\s*\/\s*)(>?)/g; +function parseAttr (state) { + var name_data = parseAttr_findName(state); + if (!name_data) { + re_parseAttr_selfClose.lastIndex = state.pos; + var matchTrailingSlash = re_parseAttr_selfClose.exec(state.data); + if (matchTrailingSlash && matchTrailingSlash.index === state.pos) { + if (!state.done && !matchTrailingSlash[2] && state.pos + matchTrailingSlash[0].length === state.data.length) { + state.needData = true; + return; + } + state.lastTag.raw += matchTrailingSlash[1]; + state.output.push({ type: Mode.Tag, name: '/' + state.lastTag.name, raw: null }); + state.pos += matchTrailingSlash[1].length; + } + var foundPos = state.data.indexOf('>', state.pos); + if (foundPos < 0) { + if (state.done) { //TODO: is this needed? + state.lastTag.raw += state.data.substr(state.pos); + state.pos = state.data.length; + return; + } + state.needData = true; + } else { + // state.lastTag = null; + state.pos = foundPos + 1; + state.mode = Mode.Text; + } + return; + } + if (!state.done && state.pos + name_data.match.length === state.data.length) { + state.needData = true; + return null; + } + state.pos += name_data.match.length; + var value_data = parseAttr_findValue(state); + if (value_data) { + if (!state.done && state.pos + value_data.match.length === state.data.length) { + state.needData = true; + state.pos -= name_data.match.length; + return; + } + state.pos += value_data.match.length; + } else { + re_parseAttr_splitValue.lastIndex = state.pos; + if (re_parseAttr_splitValue.exec(state.data)) { + state.needData = true; + state.pos -= name_data.match.length; + return; + } + value_data = { + match: '' + , value: null + }; + } + state.lastTag.raw += name_data.match + value_data.match; + + state.output.push({ type: Mode.Attr, name: name_data.name, data: value_data.value }); +} + +var re_parseCData_findEnding = /\]{1,2}$/; +function parseCData (state) { + var foundPos = state.data.indexOf(']]>', state.pos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + re_parseCData_findEnding.lastIndex = state.pos; + var matchPartialCDataEnd = re_parseCData_findEnding.exec(state.data); + if (matchPartialCDataEnd) { + state.needData = true; + return; + } + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + state.output.push({ type: Mode.CData, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 3; + } +} + +var re_parseComment_findEnding = /\-{1,2}$/; +function parseComment (state) { + var foundPos = state.data.indexOf('-->', state.pos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + re_parseComment_findEnding.lastIndex = state.pos; + var matchPartialCommentEnd = re_parseComment_findEnding.exec(state.data); + if (matchPartialCommentEnd) { + state.needData = true; + return; + } + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + state.output.push({ type: Mode.Comment, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 3; + } +} + +function parse (state) { + switch (state.mode) { + case Mode.Text: + return parseText(state); + case Mode.Tag: + return parseTag(state); + case Mode.Attr: + return parseAttr(state); + case Mode.CData: + return parseCData(state); + case Mode.Comment: + return parseComment(state); + } +} + +function Parser (handler, options) { + this._options = options ? options : { }; + if (this._options.includeLocation == undefined) { + this._options.includeLocation = false; //Do not track element position in document by default + } + + this.validateHandler(handler); + var self = this; + this._handler = handler; + this.reset(); +} + + Parser.prototype.reset = function Parser$reset () { + this.state = { + mode: Mode.Text, + pos: 0, + data: null, + pendingText: null, + lastTag: null, + isScript: false, + needData: false, + // output: [], + done: false + }; + }; + + Parser.prototype.parseChunk = function Parser$parseChunk (chunk) { + this.state.needData = false; + this.state.data = (this.state.data !== null) ? + this.state.data.substr(this.pos) + chunk + : + chunk + ; + while (this.state.pos < this.state.data.length && !this.state.needData) { + parse(this.state); + } + }; + + Parser.prototype.parseComplete = function Parser$parseComplete (data) { + this.reset(); + this.parseChunk(data); + this.done(); + } + + Parser.prototype.done = function Parser$done () { + this.state.done = true; + parse(this.state); + + }; + + Parser.prototype.validateHandler = function Parser$validateHandler (handler) { + if ((typeof handler) != "object") { + throw new Error("Handler is not an object"); + } + if ((typeof handler.reset) != "function") { + throw new Error("Handler method 'reset' is invalid"); + } + if ((typeof handler.done) != "function") { + throw new Error("Handler method 'done' is invalid"); + } + if ((typeof handler.write) != "function") { + throw new Error("Handler method 'write' is invalid"); + } + if ((typeof handler.error) != "function") { + throw new Error("Handler method 'error' is invalid"); + } + } + +// Parser.prototype.done_old = function Parser$done_old () { +// if (this.state.pendingText) { +// this.state.output.push({ type: this.state.mode, data: this.state.pendingText.join('') }); +// this.state.pendingText = null; +// } +// console.log(this.state); + +// var buffer = []; +// var lastType; +// for (var i = 0, len = this.state.output.length; i < len; i++) { +// var node = this.state.output[i]; +// if ((lastType === Mode.Attr && node.type !== Mode.Attr) || (lastType === Mode.Tag && node.type !== Mode.Attr)) { +// buffer.push('>'); +// } +// switch (node.type) { + +// case Mode.Text: +// buffer.push(node.data); +// break; + +// case Mode.Comment: +// buffer.push(''); +// break; + +// case Mode.CData: +// buffer.push(''); +// break; + +// case Mode.Tag: +// buffer.push('<', node.name); +// break; + +// case Mode.Attr: +// var quoteChar = (node.value.indexOf('\'') < 0) ? '\'' : '"'; +// buffer.push(' ', node.name, '=', quoteChar, node.value, quoteChar); +// break; + +// } +// lastType = node.type; +// } +// if (lastType === Mode.Tag || lastType === Mode.Attr) { +// buffer.push('>'); +// } +// console.log(buffer.join('')); +// }; + +function HtmlHandler (options, callback) { + this.reset(); + this._options = options ? options : { }; + if (this._options.ignoreWhitespace == undefined) { + this._options.ignoreWhitespace = false; //Keep whitespace-only text nodes + } + if (this._options.trackPosition == undefined) { + this._options.trackPosition = false; //Include position of element (row, col) on nodes + } + if (this._options.verbose == undefined) { + this._options.verbose = true; //Keep data property for tags and raw property for all + } + if (this._options.enforceEmptyTags == undefined) { + this._options.enforceEmptyTags = true; //Don't allow children for HTML tags defined as empty in spec + } + if (this._options.caseSensitiveTags == undefined) { + this._options.caseSensitiveTags = false; //Lowercase all tag names + } + if (this._options.caseSensitiveAttr == undefined) { + this._options.caseSensitiveAttr = false; //Lowercase all attribute names + } + if ((typeof callback) == "function") { + this._callback = callback; + } +} + + //**"Static"**// + //HTML Tags that shouldn't contain child nodes + HtmlHandler._emptyTags = { + area: 1 + , base: 1 + , basefont: 1 + , br: 1 + , col: 1 + , frame: 1 + , hr: 1 + , img: 1 + , input: 1 + , isindex: 1 + , link: 1 + , meta: 1 + , param: 1 + , embed: 1 + } + //Regex to detect whitespace only text nodes + HtmlHandler.reWhitespace = /^\s*$/; + + //**Public**// + //Properties// + HtmlHandler.prototype.dom = null; //The hierarchical object containing the parsed HTML + //Methods// + //Resets the handler back to starting state + HtmlHandler.prototype.reset = function HtmlHandler$reset() { + this.dom = []; + this._done = false; + this._tagStack = []; + this._tagStack.last = function HtmlHandler$_tagStack$last () { + return(this.length ? this[this.length - 1] : null); + } + } + //Signals the handler that parsing is done + HtmlHandler.prototype.done = function HtmlHandler$done () { + this._done = true; + this.handleCallback(null); + } + + HtmlHandler.prototype.error = function HtmlHandler$error (error) { + this.handleCallback(error); + } + + HtmlHandler.prototype.handleCallback = function HtmlHandler$handleCallback (error) { + if ((typeof this._callback) != "function") + if (error) + throw error; + else + return; + this._callback(error, this.dom); + } + + HtmlHandler.prototype.isEmptyTag = function HtmlHandler$isEmptyTag (element) { + var name = element.name.toLowerCase(); + if (name.charAt(0) == '/') { + name = name.substring(1); + } + return this._options.enforceEmptyTags && !!HtmlHandler._emptyTags[name]; + }; + + HtmlHandler.prototype._copyElement = function HtmlHandler$_copyElement (element) { + var newElement = { type: element.type }; + + if (this._options.verbose && element['raw'] !== undefined) { + newElement.raw = element.raw; + } + if (element['name'] !== undefined) { + switch (element.type) { + + case Mode.Tag: + newElement.name = this._options.caseSensitiveTags ? + element.name + : + element.name.toLowerCase() + ; + break; + + case Mode.Attr: + newElement.name = this._options.caseSensitiveAttr ? + element.name + : + element.name.toLowerCase() + ; + break; + + default: + newElement.name = this._options.caseSensitiveTags ? + element.name + : + element.name.toLowerCase() + ; + break; + + } + } + if (element['data'] !== undefined) { + newElement.data = element.name; + } + + return newElement; + } + + HtmlHandler.prototype.write = function HtmlHandler$write (element) { + if (this._done) { + this.handleCallback(new Error("Writing to the handler after done() called is not allowed without a reset()")); + } + if (element.type === Mode.Text && this._options.ignoreWhitespace) { + if (HtmlHandler.reWhitespace.test(element.data)) { + return; + } + } + var node; + if (!this._options.verbose) { +// element.raw = null; //FIXME: Not clean + //FIXME: Serious performance problem using delete + delete element.raw; + if (element.type == "tag" || element.type == "script" || element.type == "style") { + delete element.data; + } + } + if (!this._tagStack.last()) { //There are no parent elements + //If the element can be a container, add it to the tag stack and the top level list + if (element.type != Mode.Text && element.type != Mode.Comment && element.type != Mode.CData) { + if (element.name.charAt(0) != "/") { //Ignore closing tags that obviously don't have an opening tag + node = this._copyElement(element); + this.dom.push(node); + if (!this.isEmptyTag(node)) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(node); + } + } + } + else //Otherwise just add to the top level list + this.dom.push(this._copyElement(element)); + } + else { //There are parent elements + //If the element can be a container, add it as a child of the element + //on top of the tag stack and then add it to the tag stack + if (element.type != Mode.Text && element.type != Mode.Comment && element.type != Mode.CData) { + if (element.name.charAt(0) == "/") { + //This is a closing tag, scan the tagStack to find the matching opening tag + //and pop the stack up to the opening tag's parent + var baseName = this._options.caseSensitiveTags ? + element.name.substring(1) + : + element.name.substring(1).toLowerCase() + ; + if (!this.isEmptyTag(element)) { + var pos = this._tagStack.length - 1; + while (pos > -1 && this._tagStack[pos--].name != baseName) { } + if (pos > -1 || this._tagStack[0].name == baseName) { + while (pos < this._tagStack.length - 1) { + this._tagStack.pop(); + } + } + } + } + else { //This is not a closing tag + if (!this._tagStack.last().children) { + this._tagStack.last().children = []; + } + node = this._copyElement(element); + this._tagStack.last().children.push(node); + if (!this.isEmptyTag(node)) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(node); + } + } + } + else { //This is not a container element + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(this._copyElement(element)); + } + } + } + + + //**Private**// + //Properties// + HtmlHandler.prototype._options = null; //Handler options for how to behave + HtmlHandler.prototype._callback = null; //Callback to respond to when parsing done + HtmlHandler.prototype._done = false; //Flag indicating whether handler has been notified of parsing completed + HtmlHandler.prototype._tagStack = null; //List of parents to the currently element being processed + //Methods// + +exports.Parser = Parser; + +exports.HtmlHandler = HtmlHandler; + +// exports.RssHandler = RssHandler; + +exports.ElementType = Mode; + +// exports.DomUtils = DomUtils; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/new/parser.zip b/node_modules/jsdom/node_modules/htmlparser/new/parser.zip new file mode 100644 index 0000000000000000000000000000000000000000..c562a64512784d95e30aa3980b51a05325ba1305 GIT binary patch literal 6706 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 Kw=(&k?!N%TNN0fn literal 0 HcmV?d00001 diff --git a/node_modules/jsdom/node_modules/htmlparser/new/test01.js b/node_modules/jsdom/node_modules/htmlparser/new/test01.js new file mode 100644 index 0000000..3582584 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/new/test01.js @@ -0,0 +1,258 @@ +var data = "\ +starting text\n\ +aaabbb\n\ +\n\ +< htmL >\n\ + \n\ +
\n\ +
xxx
\n\ +
yyyyyyyyyyyy
\n\ +
zzzz zzz
\n\ +
aaaa
\n\ + \n\ +\n\ +ending text\ +]+)(\s*)(>?)/g; +function parseTag (state) { + // console.log('parseTag', state); + // console.log('parseTag'); + re_parseTag.lastIndex = state.pos; + var match = re_parseTag.exec(state.data); + if (match) { + if (match[2].substr(0, 3) === '!--') { + state.mode = Mode.Comment; + state.pos += 3; + return; + } + if (match[2].substr(0, 8) === '![CDATA[') { + state.mode = Mode.CData; + state.pos += 8; + return; + } + var raw; + if (match[4] === '>') { + state.mode = Mode.Text; + raw = match[0].substr(0, match[0].length - 1); + } else { + state.mode = Mode.Attr; + raw = match[0]; + } + state.pos += match[0].length; + var tag = { type: Mode.Tag, name: match[2].toLowerCase(), name_raw: match[2], raw: raw }; + if (state.mode === Mode.Attr) { + state.lastTag = tag; + } + state.output.push(tag); + } else { + //TODO: end of tag? + //TODO: push to pending? + state.needData = true; + } +} + +var re_parseAttr_findName = /\s*([^=<>\s'"]+)\s*/g; +function parseAttr_findName (state) { + re_parseAttr_findName.lastIndex = state.pos; + var match = re_parseAttr_findName.exec(state.data); + if (!match) { + return null; + } + if (state.pos + match[0].length !== re_parseAttr_findName.lastIndex) { + return null; + } + state.pos += match[0].length; + state.lastTag.raw += match[0]; + return match[1]; +} +var re_parseAttr_findValue = /\s*=\s*(?:'([^']*)'|"([^"]*)"|([^'"\s>]*))/g; +function parseAttr_findValue (state) { + re_parseAttr_findValue.lastIndex = state.pos; + var match = re_parseAttr_findValue.exec(state.data); + if (!match) { + return null; + } + if (state.pos + match[0].length !== re_parseAttr_findValue.lastIndex) { + return null; + } + state.pos += match[0].length; + state.lastTag.raw += match[0]; + return match[1] || match[2] || match[3]; +}; +function parseAttr (state) { + // console.log('parseAttr', state); + // console.log('parseAttr'); + var name = parseAttr_findName(state); + if (!name) { + var foundPos = state.data.indexOf('>', state.pos); + if (foundPos < 0) { + state.needData = true; + } else { + state.lastTag = null; + state.pos = foundPos + 1; + state.mode = Mode.Text; + } + return; + } + state.output.push({ type: Mode.Attr, name: name, name_raw: name.toLowerCase(), value: parseAttr_findValue(state) }); +} + +function parseCData (state) { + // console.log('parseCData', state); + // console.log('parseCData'); + var foundPos = state.data.indexOf(']]>', state.pos); + if (foundPos < 0) { + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + state.output.push({ type: Mode.CData, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 3; + } +} + +function parseComment (state) { + // console.log('parseComment', state); + // console.log('parseComment'); + var foundPos = state.data.indexOf('-->', state.pos); + if (foundPos < 0) { + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + state.output.push({ type: Mode.Comment, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 3; + } +} + +while (state.pos < state.data.length && !state.needData) { + parse(state); +} +if (state.pendingText) { + state.output.push({ type: state.mode, data: state.pendingText }); + state.pendingText = null; +} +console.log(state); + +var buffer = []; +var lastType; +for (var i = 0, len = state.output.length; i < len; i++) { + var node = state.output[i]; + if ((lastType === Mode.Attr && node.type !== Mode.Attr) || (lastType === Mode.Tag && node.type !== Mode.Attr)) { + buffer.push('>'); + } + switch (node.type) { + + case Mode.Text: + buffer.push(node.data); + break; + + case Mode.Comment: + buffer.push(''); + break; + + case Mode.CData: + buffer.push(''); + break; + + case Mode.Tag: + buffer.push('<', node.name); + break; + + case Mode.Attr: + var quoteChar = (node.value.indexOf('\'') < 0) ? '\'' : '"'; + buffer.push(' ', node.name, '=', quoteChar, node.value, quoteChar); + break; + + } + lastType = node.type; +} +if (lastType === Mode.Tag || lastType === Mode.Attr) { + buffer.push('>'); +} +console.log(buffer.join('')); diff --git a/node_modules/jsdom/node_modules/htmlparser/new/test02.js b/node_modules/jsdom/node_modules/htmlparser/new/test02.js new file mode 100644 index 0000000..6221c95 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/new/test02.js @@ -0,0 +1,856 @@ +var htmlparser = require('./htmlparser'); + +var tests = { + + 'plain text': { + data: ['This is the text'] + , expected: [{ type: 'text', data: 'This is the text' }] + } + + , 'split text': { + data: ['This is', ' the text'] + , expected: [{ type: 'text', data: 'This is the text' }] + } + + , 'simple tag': { + data: ['
'] + , expected: [{ type: 'tag', name: 'div', name_raw: 'div', raw: 'div' }] + } + + , 'simple comment': { + data: [''] + , expected: [{ type: 'comment', data: ' content ' }] + } + + , 'simple cdata': { + data: [''] + , expected: [{ type: 'cdata', data: ' content ' }] + } + + , 'split simple tag #1': { + data: ['<', 'div>'] + , expected: [{ type: 'tag', name: 'div', name_raw: 'div', raw: 'div' }] + } + + , 'split simple tag #2': { + data: [''] + , expected: [{ type: 'tag', name: 'div', name_raw: 'div', raw: 'div' }] + } + + , 'split simple tag #3': { + data: [''] + , expected: [{ type: 'tag', name: 'div', name_raw: 'div', raw: 'div' }] + } + + , 'text before tag': { + data: ['xxx
'] + , expected: [ + { type: 'text', data: 'xxx'}, + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div' } + ] + } + + , 'text after tag': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div' }, + { type: 'text', data: 'xxx'} + ] + } + + , 'text inside tag': { + data: ['
xxx
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div' }, + { type: 'text', data: 'xxx'}, + { type: 'tag', name: '/div', name_raw: '/div', raw: '/div' } + ] + } + + , 'attribute with single quotes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=\'1\'' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'} + ] + } + + , 'attribute with double quotes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a="1"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'} + ] + } + + , 'attribute with no quotes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=1' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'} + ] + } + + , 'attribute with no value': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div wierd' }, + { type: 'attr', name:'wierd', name_raw: 'wierd', value: null} + ] + } + + , 'attribute with no value, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div wierd' }, + { type: 'attr', name:'wierd', name_raw: 'wierd', value: null}, + { type: 'text', data: 'xxx' } + ] + } + + , 'tag with multiple attributes': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a="1" b="2"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'} + ] + } + + , 'tag with multiple attributes, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a="1" b="2"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'text', data: 'xxx' } + ] + } + + , 'tag with mixed attributes #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=1 b=\'2\' c="3"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'} + ] + } + + , 'tag with mixed attributes #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=1 b="2" c=\'3\'' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'} + ] + } + + , 'tag with mixed attributes #3': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=\'1\' b=2 c="3"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'} + ] + } + + , 'tag with mixed attributes #4': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=\'1\' b="2" c=3' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'} + ] + } + + , 'tag with mixed attributes #5': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a="1" b=2 c=\'3\'' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'} + ] + } + + , 'tag with mixed attributes #6': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a="1" b=\'2\' c="3"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'} + ] + } + + , 'tag with mixed attributes, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=1 b=\'2\' c="3"' }, + { type: 'attr', name:'a', name_raw: 'a', value: '1'}, + { type: 'attr', name:'b', name_raw: 'b', value: '2'}, + { type: 'attr', name:'c', name_raw: 'c', value: '3'}, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'self closing tag, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null }, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag with spaces #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div /' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'self closing tag with spaces #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div/ ' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'self closing tag with spaces #3': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div / ' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'self closing tag with spaces, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div / ' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null }, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag with attribute': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=b /' }, + { type: 'attr', name:'a', name_raw: 'a', value: 'b'}, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'self closing tag with attribute, trailing text': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a=b /' }, + { type: 'attr', name:'a', name_raw: 'a', value: 'b'}, + { type: 'tag', name: '/div', name_raw: '/div', raw: null }, + { type: 'text', data: 'xxx' } + ] + } + + , 'self closing tag split #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'self closing tag split #2': { + data: [''] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div/' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: null } + ] + } + + , 'attribute missing close quote': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div a="1>'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'split attribute #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'split attribute #3': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'split attribute #4': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'split attribute #5': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'split attribute #6': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'attribute split from tag #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'attribute split from tag #2': { + data: [''] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="yyy"' }, + { type: 'attr', name:'xxx', name_raw: 'xxx', value: 'yyy'} + ] + } + + , 'text before complex tag': { + data: ['xxx
'] + , expected: [ + { type: 'text', data: 'xxx' }, + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div yyy="123"'}, + { type: 'attr', name: 'yyy', name_raw: 'yyy', value: '123' } + ] + } + + , 'text after complex tag': { + data: ['
xxx'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div yyy="123"'}, + { type: 'attr', name: 'yyy', name_raw: 'yyy', value: '123' }, + { type: 'text', data: 'xxx' } + ] + } + + , 'text inside complex tag': { + data: ['
xxx
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div yyy="123"'}, + { type: 'attr', name: 'yyy', name_raw: 'yyy', value: '123' }, + { type: 'text', data: 'xxx' }, + { type: 'tag', name: '/div', name_raw: '/div', raw: '/div'} + ] + } + + , 'nested tags': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div'}, + { type: 'tag', name: 'span', name_raw: 'span', raw: 'span'}, + { type: 'tag', name: '/span', name_raw: '/span', raw: '/span'}, + { type: 'tag', name: '/div', name_raw: '/div', raw: '/div'} + ] + } + + , 'nested tags with attributes': { + data: ['
xxx
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div aaa="bbb"'}, + { type: 'attr', name: 'aaa', name_raw: 'aaa', value: 'bbb' }, + { type: 'tag', name: 'span', name_raw: 'span', raw: 'span 123=\'456\''}, + { type: 'attr', name: '123', name_raw: '123', value: '456' }, + { type: 'text', data: 'xxx' }, + { type: 'tag', name: '/span', name_raw: '/span', raw: '/span'}, + { type: 'tag', name: '/div', name_raw: '/div', raw: '/div'} + ] + } + + , 'comment inside tag': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div'}, + { type: 'comment', data: ' comment text '}, + { type: 'tag', name: '/div', name_raw: '/div', raw: '/div'} + ] + } + + , 'cdata inside tag': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div'}, + { type: 'cdata', data: ' CData content '}, + { type: 'tag', name: '/div', name_raw: '/div', raw: '/div'} + ] + } + + , 'html inside comment': { + data: [''] + , expected: [{ type: 'comment', data: '
foo
'}] + } + + , 'html inside cdata': { + data: ['foo
]]>'] + , expected: [{ type: 'cdata', data: '
foo
'}] + } + + , 'quotes in attribute #1': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx=\'a"b\''}, + { type: 'attr', name: 'xxx', name_raw: 'xxx', value: 'a"b' } + ] + } + + , 'quotes in attribute #2': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="a\'b"'}, + { type: 'attr', name: 'xxx', name_raw: 'xxx', value: 'a\'b' } + ] + } + + , 'brackets in attribute': { + data: ['
'] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: 'div xxx="
"'}, + { type: 'attr', name: 'xxx', name_raw: 'xxx', value: '
' } + ] + } + + , 'split comment #1': { + data: ['<','!-- comment text -->xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #2': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #3': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #4': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #5': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #6': { + data: ['xxx'] + , expected: [ + { type: 'comment', data: ' comment text '}, + { type: 'text', data: 'xxx' } + ] + } + + , 'split comment #7': { + data: ['"] + , expected: [ + { type: 'comment', data: "\ncomment text\n" } + ] + } + + , 'cdata comment': { + data: [""] + , expected: [ + { type: 'cdata', data: "\nCData content\n" } + ] + } + + , 'multiline attribute #1': { + data: ["
"] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: "div id='\nxxx\nyyy\n'" }, + { type: 'attr', name: 'id', name_raw: 'id', value: "\nxxx\nyyy\n" } + ] + } + + , 'multiline attribute #2': { + data: ["
"] + , expected: [ + { type: 'tag', name: 'div', name_raw: 'div', raw: "div id=\"\nxxx\nyyy\n\"" }, + { type: 'attr', name: 'id', name_raw: 'id', value: "\nxxx\nyyy\n" } + ] + } + + // script tags + // style tags + +}; + +function runTests (permutator) { + var parser = new htmlparser(); + + var passed = 0; + var failed = 0; + + console.time('Tests'); + for (var testName in tests) { + var test = permutator ? permutator(tests[testName]) : tests[testName]; + process.stdout.write('[TEST] ' + testName + ' : '); + parser.reset(); + for (var i = 0, len = test.data.length; i < len; i++) { + parser.parse(test.data[i]); + } + parser.done(); + var expected = JSON.stringify(test.expected); + var result = JSON.stringify(parser.state.output); + if (expected !== result) { + failed++; + process.stdout.write("FAIL\n"); + console.log(' [EXPECTED]', expected); + console.log(' [ RESULT ]', result); + } else { + passed++; + process.stdout.write("Ok\n"); + } + } + console.timeEnd('Tests'); + console.log('Passed tests: ' + passed + '/' + (passed + failed) + ' (' + Math.round(passed / (passed + failed) * 100) + '%)'); +} + +runTests(); +runTests(function (test) { + test.data = test.data.join('').split(''); + return test; +}); diff --git a/node_modules/jsdom/node_modules/htmlparser/newparser.js b/node_modules/jsdom/node_modules/htmlparser/newparser.js new file mode 100644 index 0000000..2487f23 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/newparser.js @@ -0,0 +1,54 @@ +//node --prof --prof_auto profile.js +//deps/v8/tools/mac-tick-processor v8.log +var sys = require("sys"); +var fs = require("fs"); + +var testHtml = "./testdata/api.html"; //Test HTML file to load +var testIterations = 100; //Number of test loops to run + +var html = fs.readFileSync(testHtml).toString(); + +function getMillisecs () { + return((new Date()).getTime()); +} + +function timeExecutions (loops, func) { + var start = getMillisecs(); + + while (loops--) + func(); + + return(getMillisecs() - start); +} + +sys.puts("HTML Length: " + html.length); + +sys.puts("Test 1: " + timeExecutions(testIterations, function () { +// function parseText (data) { +// // +// } +// function parseTag (data) { +// // +// } +// function parseAttrib (data) { +// // +// } +// function parseComment (data) { +// // +// } + var data = html.split(""); + data.meta = { + length: data.length + , pos: 0 + } + while (data.meta.length > data.meta.pos && data[data.meta.pos++] !== ""); +// sys.puts("Found: " + [data.meta.pos, data[data.meta.pos]]); +}) + "ms"); + +sys.puts("Test 2: " + timeExecutions(testIterations, function () { + var data = html; + var dataLen = data.length; + var pos = 0; + while (dataLen > pos && data.charAt(pos++) !== ""); +// sys.puts("Found: " + [pos, data.charAt(pos)]); +}) + "ms"); diff --git a/node_modules/jsdom/node_modules/htmlparser/node-htmlparser.old.js b/node_modules/jsdom/node_modules/htmlparser/node-htmlparser.old.js new file mode 100644 index 0000000..cfc1664 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/node-htmlparser.old.js @@ -0,0 +1,754 @@ +/*********************************************** +Copyright 2010, Chris Winberry . All rights reserved. +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. +***********************************************/ +/* v1.5.0 */ + +(function () { + +function runningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!runningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + else if (this.Tautologistics.NodeHtmlParser) + return; //NodeHtmlParser already defined! + this.Tautologistics.NodeHtmlParser = {}; + exports = this.Tautologistics.NodeHtmlParser; +} + +//Types of elements found in the DOM +var ElementType = { + Text: "text" //Plain text + , Directive: "directive" //Special tag + , Comment: "comment" //Special tag + , Script: "script" //Special tag + , Style: "style" //Special tag + , Tag: "tag" //Any tag that isn't special +} + +function Parser (handler) { + this.validateHandler(handler); + this._handler = handler; + this.reset(); +} + + //**"Static"**// + //Regular expressions used for cleaning up and parsing (stateless) + Parser._reTrim = /(^\s+|\s+$)/g; //Trim leading/trailing whitespace + Parser._reTrimComment = /(^\!--|--$)/g; //Remove comment tag markup from comment contents + Parser._reWhitespace = /\s/g; //Used to find any whitespace to split on + Parser._reTagName = /^\s*(\/?)\s*([^\s\/]+)/; //Used to find the tag name for an element + + //Regular expressions used for parsing (stateful) + Parser._reAttrib = //Find attributes in a tag + /([^=<>\"\'\s]+)\s*=\s*"([^"]*)"|([^=<>\"\'\s]+)\s*=\s*'([^']*)'|([^=<>\"\'\s]+)\s*=\s*([^'"\s]+)|([^=<>\"\'\s\/]+)/g; + Parser._reTags = /[\<\>]/g; //Find tag markers + + //**Public**// + //Methods// + //Parses a complete HTML and pushes it to the handler + Parser.prototype.parseComplete = function Parser$parseComplete (data) { + this.reset(); + this.parseChunk(data); + this.done(); + } + + //Parses a piece of an HTML document + Parser.prototype.parseChunk = function Parser$parseChunk (data) { + if (this._done) + this.handleError(new Error("Attempted to parse chunk after parsing already done")); + this._buffer += data; //FIXME: this can be a bottleneck + this.parseTags(); + } + + //Tells the parser that the HTML being parsed is complete + Parser.prototype.done = function Parser$done () { + if (this._done) + return; + this._done = true; + + //Push any unparsed text into a final element in the element list + if (this._buffer.length) { + var rawData = this._buffer; + this._buffer = ""; + var element = { + raw: rawData + , data: (this._parseState == ElementType.Text) ? rawData : rawData.replace(Parser._reTrim, "") + , type: this._parseState + }; + if (this._parseState == ElementType.Tag || this._parseState == ElementType.Script || this._parseState == ElementType.Style) + element.name = this.parseTagName(element.data); + this.parseAttribs(element); + this._elements.push(element); + } + + this.writeHandler(); + this._handler.done(); + } + + //Resets the parser to a blank state, ready to parse a new HTML document + Parser.prototype.reset = function Parser$reset () { + this._buffer = ""; + this._done = false; + this._elements = []; + this._elementsCurrent = 0; + this._current = 0; + this._next = 0; + this._parseState = ElementType.Text; + this._prevTagSep = ''; + this._tagStack = []; + this._handler.reset(); + } + + //**Private**// + //Properties// + Parser.prototype._handler = null; //Handler for parsed elements + Parser.prototype._buffer = null; //Buffer of unparsed data + Parser.prototype._done = false; //Flag indicating whether parsing is done + Parser.prototype._elements = null; //Array of parsed elements + Parser.prototype._elementsCurrent = 0; //Pointer to last element in _elements that has been processed + Parser.prototype._current = 0; //Position in data that has already been parsed + Parser.prototype._next = 0; //Position in data of the next tag marker (<>) + Parser.prototype._parseState = ElementType.Text; //Current type of element being parsed + Parser.prototype._prevTagSep = ''; //Previous tag marker found + //Stack of element types previously encountered; keeps track of when + //parsing occurs inside a script/comment/style tag + Parser.prototype._tagStack = null; + + //Methods// + //Takes an array of elements and parses any found attributes + Parser.prototype.parseTagAttribs = function Parser$parseTagAttribs (elements) { + var idxEnd = elements.length; + var idx = 0; + + while (idx < idxEnd) { + var element = elements[idx++]; + if (element.type == ElementType.Tag || element.type == ElementType.Script || element.type == ElementType.style) + this.parseAttribs(element); + } + + return(elements); + } + + //Takes an element and adds an "attribs" property for any element attributes found + Parser.prototype.parseAttribs = function Parser$parseAttribs (element) { + //Only parse attributes for tags + if (element.type != ElementType.Script && element.type != ElementType.Style && element.type != ElementType.Tag) + return; + + var tagName = element.data.split(Parser._reWhitespace, 1)[0]; + var attribRaw = element.data.substring(tagName.length); + if (attribRaw.length < 1) + return; + + var match; + Parser._reAttrib.lastIndex = 0; + while (match = Parser._reAttrib.exec(attribRaw)) { + if (element.attribs == undefined) + element.attribs = {}; + + if (typeof match[1] == "string" && match[1].length) { + element.attribs[match[1]] = match[2]; + } else if (typeof match[3] == "string" && match[3].length) { + element.attribs[match[3].toString()] = match[4].toString(); + } else if (typeof match[5] == "string" && match[5].length) { + element.attribs[match[5]] = match[6]; + } else if (typeof match[7] == "string" && match[7].length) { + element.attribs[match[7]] = match[7]; + } + } + } + + //Extracts the base tag name from the data value of an element + Parser.prototype.parseTagName = function Parser$parseTagName (data) { + if (data == null || data == "") + return(""); + var match = Parser._reTagName.exec(data); + if (!match) + return(""); + return((match[1] ? "/" : "") + match[2]); + } + + //Parses through HTML text and returns an array of found elements + //I admit, this function is rather large but splitting up had an noticeable impact on speed + Parser.prototype.parseTags = function Parser$parseTags () { + var bufferEnd = this._buffer.length - 1; + while (Parser._reTags.test(this._buffer)) { + this._next = Parser._reTags.lastIndex - 1; + var tagSep = this._buffer.charAt(this._next); //The currently found tag marker + var rawData = this._buffer.substring(this._current, this._next); //The next chunk of data to parse + + //A new element to eventually be appended to the element list + var element = { + raw: rawData + , data: (this._parseState == ElementType.Text) ? rawData : rawData.replace(Parser._reTrim, "") + , type: this._parseState + }; + + var elementName = this.parseTagName(element.data); + + //This section inspects the current tag stack and modifies the current + //element if we're actually parsing a special area (script/comment/style tag) + if (this._tagStack.length) { //We're parsing inside a script/comment/style tag + if (this._tagStack[this._tagStack.length - 1] == ElementType.Script) { //We're currently in a script tag + if (elementName == "/script") //Actually, we're no longer in a script tag, so pop it off the stack + this._tagStack.pop(); + else { //Not a closing script tag + if (element.raw.indexOf("!--") != 0) { //Make sure we're not in a comment + //All data from here to script close is now a text element + element.type = ElementType.Text; + //If the previous element is text, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Text) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep + element.raw; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + } + } + } + } + else if (this._tagStack[this._tagStack.length - 1] == ElementType.Style) { //We're currently in a style tag + if (elementName == "/style") //Actually, we're no longer in a style tag, so pop it off the stack + this._tagStack.pop(); + else { + if (element.raw.indexOf("!--") != 0) { //Make sure we're not in a comment + //All data from here to style close is now a text element + element.type = ElementType.Text; + //If the previous element is text, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Text) { + if (element.raw != "") { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep + element.raw; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + } + else //Element is empty, so just append the last tag marker found + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep; + } + else //The previous element was not text + if (element.raw != "") + element.raw = element.data = element.raw; + } + } + } + else if (this._tagStack[this._tagStack.length - 1] == ElementType.Comment) { //We're currently in a comment tag + var rawLen = element.raw.length; + if (element.raw.charAt(rawLen - 2) == "-" && element.raw.charAt(rawLen - 1) == "-" && tagSep == ">") { + //Actually, we're no longer in a style tag, so pop it off the stack + this._tagStack.pop(); + //If the previous element is a comment, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Comment) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = (prevElement.raw + element.raw).replace(Parser._reTrimComment, ""); + element.raw = element.data = ""; //This causes the current element to not be added to the element list + element.type = ElementType.Text; + } + else //Previous element not a comment + element.type = ElementType.Comment; //Change the current element's type to a comment + } + else { //Still in a comment tag + element.type = ElementType.Comment; + //If the previous element is a comment, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Comment) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + element.raw + tagSep; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + element.type = ElementType.Text; + } + else + element.raw = element.data = element.raw + tagSep; + } + } + } + + //Processing of non-special tags + if (element.type == ElementType.Tag) { + element.name = elementName; + + if (element.raw.indexOf("!--") == 0) { //This tag is really comment + element.type = ElementType.Comment; + delete element["name"]; + var rawLen = element.raw.length; + //Check if the comment is terminated in the current element + if (element.raw.charAt(rawLen - 1) == "-" && element.raw.charAt(rawLen - 2) == "-" && tagSep == ">") + element.raw = element.data = element.raw.replace(Parser._reTrimComment, ""); + else { //It's not so push the comment onto the tag stack + element.raw += tagSep; + this._tagStack.push(ElementType.Comment); + } + } + else if (element.raw.indexOf("!") == 0 || element.raw.indexOf("?") == 0) { + element.type = ElementType.Directive; + //TODO: what about CDATA? + } + else if (element.name == "script") { + element.type = ElementType.Script; + //Special tag, push onto the tag stack if not terminated + if (element.data.charAt(element.data.length - 1) != "/") + this._tagStack.push(ElementType.Script); + } + else if (element.name == "/script") + element.type = ElementType.Script; + else if (element.name == "style") { + element.type = ElementType.Style; + //Special tag, push onto the tag stack if not terminated + if (element.data.charAt(element.data.length - 1) != "/") + this._tagStack.push(ElementType.Style); + } + else if (element.name == "/style") + element.type = ElementType.Style; + if (element.name && element.name.charAt(0) == "/") + element.data = element.name; + } + + //Add all tags and non-empty text elements to the element list + if (element.raw != "" || element.type != ElementType.Text) { + this.parseAttribs(element); + this._elements.push(element); + //If tag self-terminates, add an explicit, separate closing tag + if ( + element.type != ElementType.Text + && + element.type != ElementType.Comment + && + element.type != ElementType.Directive + && + element.data.charAt(element.data.length - 1) == "/" + ) + this._elements.push({ + raw: "/" + element.name + , data: "/" + element.name + , name: "/" + element.name + , type: element.type + }); + } + this._parseState = (tagSep == "<") ? ElementType.Tag : ElementType.Text; + this._current = this._next + 1; + this._prevTagSep = tagSep; + } + + this._buffer = (this._current <= bufferEnd) ? this._buffer.substring(this._current) : ""; + this._current = 0; + + this.writeHandler(); + } + + //Checks the handler to make it is an object with the right "interface" + Parser.prototype.validateHandler = function Parser$validateHandler (handler) { + if ((typeof handler) != "object") + throw new Error("Handler is not an object"); + if ((typeof handler.reset) != "function") + throw new Error("Handler method 'reset' is invalid"); + if ((typeof handler.done) != "function") + throw new Error("Handler method 'done' is invalid"); + if ((typeof handler.writeTag) != "function") + throw new Error("Handler method 'writeTag' is invalid"); + if ((typeof handler.writeText) != "function") + throw new Error("Handler method 'writeText' is invalid"); + if ((typeof handler.writeComment) != "function") + throw new Error("Handler method 'writeComment' is invalid"); + if ((typeof handler.writeDirective) != "function") + throw new Error("Handler method 'writeDirective' is invalid"); + } + + //Writes parsed elements out to the handler + Parser.prototype.writeHandler = function Parser$writeHandler (forceFlush) { + forceFlush = !!forceFlush; + if (this._tagStack.length && !forceFlush) + return; + while (this._elements.length) { + var element = this._elements.shift(); + switch (element.type) { + case ElementType.Comment: + this._handler.writeComment(element); + break; + case ElementType.Directive: + this._handler.writeDirective(element); + break; + case ElementType.Text: + this._handler.writeText(element); + break; + default: + this._handler.writeTag(element); + break; + } + } + } + + Parser.prototype.handleError = function Parser$handleError (error) { + if ((typeof this._handler.error) == "function") + this._handler.error(error); + else + throw error; + } + +//TODO: make this a trully streamable handler +function RssHandler (callback) { + RssHandler.super_.call(this, callback, { ignoreWhitespace: true, verbose: false, enforceEmptyTags: false }); +} +inherits(RssHandler, DefaultHandler); + + RssHandler.prototype.done = function RssHandler$done () { + var feed = { }; + var feedRoot; + + var found = DomUtils.getElementsByTagName(function (value) { return(value == "rss" || value == "feed"); }, this.dom, false); + if (found.length) { + feedRoot = found[0]; + } + if (feedRoot) { + if (feedRoot.name == "rss") { + feed.type = "rss"; + feedRoot = feedRoot.children[0]; // + feed.id = ""; +// require("sys").debug(require("sys").inspect(feedRoot, false, null)); +// require("sys").debug(require("sys").inspect(DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data, false, null)); + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("description", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("lastBuildDate", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("managingEditor", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("item", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("guid", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("description", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("pubDate", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } else { + feed.type = "atom"; + try { + feed.id = DomUtils.getElementsByTagName("id", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].attribs.href; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("subtitle", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("updated", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("email", feedRoot.children, true)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("entry", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("id", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].attribs.href; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("summary", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("updated", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } + + this.dom = feed; + } + RssHandler.super_.prototype.done.call(this); + } + +/////////////////////////////////////////////////// + +function DefaultHandler (callback, options) { + this.reset(); + this._options = options ? options : { }; + if (this._options.ignoreWhitespace == undefined) + this._options.ignoreWhitespace = false; //Keep whitespace-only text nodes + if (this._options.verbose == undefined) + this._options.verbose = true; //Keep data property for tags and raw property for all + if (this._options.enforceEmptyTags == undefined) + this._options.enforceEmptyTags = true; //Don't allow children for HTML tags defined as empty in spec + if ((typeof callback) == "function") + this._callback = callback; +} + + //**"Static"**// + //HTML Tags that shouldn't contain child nodes + DefaultHandler._emptyTags = { + area: 1 + , base: 1 + , basefont: 1 + , br: 1 + , col: 1 + , frame: 1 + , hr: 1 + , img: 1 + , input: 1 + , isindex: 1 + , link: 1 + , meta: 1 + , param: 1 + , embed: 1 + } + //Regex to detect whitespace only text nodes + DefaultHandler.reWhitespace = /^\s*$/; + + //**Public**// + //Properties// + DefaultHandler.prototype.dom = null; //The hierarchical object containing the parsed HTML + //Methods// + //Resets the handler back to starting state + DefaultHandler.prototype.reset = function DefaultHandler$reset() { + this.dom = []; + this._done = false; + this._tagStack = []; + this._tagStack.last = function DefaultHandler$_tagStack$last () { + return(this.length ? this[this.length - 1] : null); + } + } + //Signals the handler that parsing is done + DefaultHandler.prototype.done = function DefaultHandler$done () { + this._done = true; + this.handleCallback(null); + } + DefaultHandler.prototype.writeTag = function DefaultHandler$writeTag (element) { + this.handleElement(element); + } + DefaultHandler.prototype.writeText = function DefaultHandler$writeText (element) { + if (this._options.ignoreWhitespace) + if (DefaultHandler.reWhitespace.test(element.data)) + return; + this.handleElement(element); + } + DefaultHandler.prototype.writeComment = function DefaultHandler$writeComment (element) { + this.handleElement(element); + } + DefaultHandler.prototype.writeDirective = function DefaultHandler$writeDirective (element) { + this.handleElement(element); + } + DefaultHandler.prototype.error = function DefaultHandler$error (error) { + this.handleCallback(error); + } + + //**Private**// + //Properties// + DefaultHandler.prototype._options = null; //Handler options for how to behave + DefaultHandler.prototype._callback = null; //Callback to respond to when parsing done + DefaultHandler.prototype._done = false; //Flag indicating whether handler has been notified of parsing completed + DefaultHandler.prototype._tagStack = null; //List of parents to the currently element being processed + //Methods// + DefaultHandler.prototype.handleCallback = function DefaultHandler$handleCallback (error) { + if ((typeof this._callback) != "function") + if (error) + throw error; + else + return; + this._callback(error, this.dom); + } + DefaultHandler.prototype.handleElement = function DefaultHandler$handleElement (element) { + if (this._done) + this.handleCallback(new Error("Writing to the handler after done() called is not allowed without a reset()")); + if (!this._options.verbose) { +// element.raw = null; //FIXME: Not clean + //FIXME: Serious performance problem using delete + delete element.raw; + if (element.type == "tag" || element.type == "script" || element.type == "style") + delete element.data; + } + if (!this._tagStack.last()) { //There are no parent elements + //If the element can be a container, add it to the tag stack and the top level list + if (element.type != ElementType.Text && element.type != ElementType.Comment && element.type != ElementType.Directive) { + if (element.name.charAt(0) != "/") { //Ignore closing tags that obviously don't have an opening tag + this.dom.push(element); + if (!this._options.enforceEmptyTags || !DefaultHandler._emptyTags[element.name]) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(element); + } + } + } + else //Otherwise just add to the top level list + this.dom.push(element); + } + else { //There are parent elements + //If the element can be a container, add it as a child of the element + //on top of the tag stack and then add it to the tag stack + if (element.type != ElementType.Text && element.type != ElementType.Comment && element.type != ElementType.Directive) { + if (element.name.charAt(0) == "/") { + //This is a closing tag, scan the tagStack to find the matching opening tag + //and pop the stack up to the opening tag's parent + var baseName = element.name.substring(1); + if (!this._options.enforceEmptyTags || !DefaultHandler._emptyTags[baseName]) { + var pos = this._tagStack.length - 1; + while (pos > -1 && this._tagStack[pos--].name != baseName) { } + if (pos > -1 || this._tagStack[0].name == baseName) + while (pos < this._tagStack.length - 1) + this._tagStack.pop(); + } + } + else { //This is not a closing tag + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(element); + if (!this._options.enforceEmptyTags || !DefaultHandler._emptyTags[element.name]) //Don't add tags to the tag stack that can't have children + this._tagStack.push(element); + } + } + else { //This is not a container element + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(element); + } + } + } + + var DomUtils = { + testElement: function DomUtils$testElement (options, element) { + if (!element) { + return(false); + } + + for (var key in options) { + if (key == "tag_name") { + if (element.type != "tag" && element.type != "script" && element.type != "style") { + return(false); + } + return(options["tag_name"](element.name)); + } else if (key == "tag_type") { + return(options["tag_type"](element.type)); + } else if (key == "tag_contains") { + if (element.type != "text" && element.type != "comment" && element.type != "directive") { + return(false); + } + return(options["tag_contains"](element.data)); + } else { + return(element.attribs && options[key](element.attribs[key])); + } + } + + return(true); + } + + , getElements: function DomUtils$getElements (options, currentElement, recurse) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + + if (!currentElement) { + return([]); + } + + var found = []; + var elementList; + + function getTest (checkVal) { + return(((typeof options[key]) == "function") ? checkVal : function (value) { return(value == checkVal); }); + } + for (var key in options) { + options[key] = getTest(options[key]); + } + + if (DomUtils.testElement(options, currentElement)) { + found.push(currentElement); + } + + if (recurse && currentElement.children) + elementList = currentElement.children; + else if (currentElement instanceof Array) + elementList = currentElement; + else + return(found); + + for (var i = 0; i < elementList.length; i++) + found = found.concat(DomUtils.getElements(options, elementList[i], recurse)); + + return(found); + } + + , getElementById: function DomUtils$getElementById (id, currentElement, recurse) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + var result = DomUtils.getElements({ id: id }, currentElement, recurse); + return(result.length ? result[0] : null); + } + + , getElementsByTagName: function DomUtils$getElementsByTagName (name, currentElement, recurse) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + return(DomUtils.getElements({ tag_name: name }, currentElement, recurse)); + } + + , getElementsByTagType: function DomUtils$getElementsByTagType (type, currentElement, recurse) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + return(DomUtils.getElements({ tag_type: type }, currentElement, recurse)); + } + } + + function inherits (ctor, superCtor) { + var tempCtor = function(){}; + tempCtor.prototype = superCtor.prototype; + ctor.super_ = superCtor; + ctor.prototype = new tempCtor(); + ctor.prototype.constructor = ctor; + } + +exports.Parser = Parser; + +exports.DefaultHandler = DefaultHandler; + +exports.RssHandler = RssHandler; + +exports.ElementType = ElementType; + +exports.DomUtils = DomUtils; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/package.json b/node_modules/jsdom/node_modules/htmlparser/package.json new file mode 100644 index 0000000..9e3a64a --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/package.json @@ -0,0 +1,44 @@ +{ + "name": "htmlparser", + "description": "Forgiving HTML/XML/RSS Parser in JS for *both* Node and Browsers", + "version": "1.7.6", + "author": { + "name": "Chris Winberry", + "email": "chris@winberry.net" + }, + "contributors": [], + "repository": { + "type": "git", + "url": "https://github.com/tautologistics/node-htmlparser" + }, + "keywords": [ + "html", + "xml", + "rss", + "parser" + ], + "directories": { + "lib": "./lib/" + }, + "main": "./lib/htmlparser", + "homepage": "http://github.com/tautologistics/node-htmlparser", + "bugs": { + "mail": "chris@winberry.net", + "url": "http://github.com/tautologistics/node-htmlparser/issues" + }, + "engines": { + "node": ">=0.1.33" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/tautologistics/node-htmlparser/raw/master/LICENSE" + } + ], + "readme": "#NodeHtmlParser\nA forgiving HTML/XML/RSS parser written in JS for both the browser and NodeJS (yes, despite the name it works just fine in any modern browser). The parser can handle streams (chunked data) and supports custom handlers for writing custom DOMs/output.\n\n##Installing\n\n\tnpm install htmlparser\n\n##Running Tests\n\n###Run tests under node:\n\tnode runtests.js\n\n###Run tests in browser:\nView runtests.html in any browser\n\n##Usage In Node\n\n```javascript\nvar htmlparser = require(\"htmlparser\");\nvar rawHtml = \"Xyz + , Style: "style" //Special tag + , Tag: "tag" //Any tag that isn't special + } + + function Parser (handler) { + this.validateHandler(handler); + this._handler = handler; + this.reset(); + } + + //**"Static"**// + //Regular expressions used for cleaning up and parsing (stateless) + Parser._reTrim = /(^\s+|\s+$)/g; //Trim leading/trailing whitespace + Parser._reTrimComment = /(^\!--|--$)/g; //Remove comment tag markup from comment contents + Parser._reWhitespace = /\s/g; //Used to find any whitespace to split on + Parser._reTagName = /^\s*(\/?)\s*([^\s\/]+)/; //Used to find the tag name for an element + + //Regular expressions used for parsing (stateful) + Parser._reAttrib = //Find attributes in a tag + /([^=<>\"\'\s]+)\s*=\s*"([^"]*)"|([^=<>\"\'\s]+)\s*=\s*'([^']*)'|([^=<>\"\'\s]+)\s*=\s*([^'"\s]+)|([^=<>\"\'\s\/]+)/g; +Parser._reTags = /[\<\>]/g; //Find tag markers + +//**Public**// +//Methods// +//Parses a complete HTML and pushes it to the handler +Parser.prototype.parseComplete = function Parser$parseComplete (data) { + this.reset(); + this.parseChunk(data); + this.done(); +} + +//Parses a piece of an HTML document +Parser.prototype.parseChunk = function Parser$parseChunk (data) { + if (this._done) + this.handleError(new Error("Attempted to parse chunk after parsing already done")); + this._buffer += data; //FIXME: this can be a bottleneck + this.parseTags(); +} + +//Tells the parser that the HTML being parsed is complete +Parser.prototype.done = function Parser$done () { + if (this._done) + return; + this._done = true; + + //Push any unparsed text into a final element in the element list + if (this._buffer.length) { + var rawData = this._buffer; + this._buffer = ""; + var element = { + raw: rawData + , data: (this._parseState == ElementType.Text) ? rawData : rawData.replace(Parser._reTrim, "") + , type: this._parseState + }; + if (this._parseState == ElementType.Tag || this._parseState == ElementType.Script || this._parseState == ElementType.Style) + element.name = this.parseTagName(element.data); + this.parseAttribs(element); + this._elements.push(element); + } + + this.writeHandler(); + this._handler.done(); +} + +//Resets the parser to a blank state, ready to parse a new HTML document +Parser.prototype.reset = function Parser$reset () { + this._buffer = ""; + this._done = false; + this._elements = []; + this._elementsCurrent = 0; + this._current = 0; + this._next = 0; + this._parseState = ElementType.Text; + this._prevTagSep = ''; + this._tagStack = []; + this._handler.reset(); +} + +//**Private**// +//Properties// +Parser.prototype._handler = null; //Handler for parsed elements +Parser.prototype._buffer = null; //Buffer of unparsed data +Parser.prototype._done = false; //Flag indicating whether parsing is done +Parser.prototype._elements = null; //Array of parsed elements +Parser.prototype._elementsCurrent = 0; //Pointer to last element in _elements that has been processed +Parser.prototype._current = 0; //Position in data that has already been parsed +Parser.prototype._next = 0; //Position in data of the next tag marker (<>) +Parser.prototype._parseState = ElementType.Text; //Current type of element being parsed +Parser.prototype._prevTagSep = ''; //Previous tag marker found +//Stack of element types previously encountered; keeps track of when +//parsing occurs inside a script/comment/style tag +Parser.prototype._tagStack = null; + +//Methods// +//Takes an array of elements and parses any found attributes +Parser.prototype.parseTagAttribs = function Parser$parseTagAttribs (elements) { + var idxEnd = elements.length; + var idx = 0; + + while (idx < idxEnd) { + var element = elements[idx++]; + if (element.type == ElementType.Tag || element.type == ElementType.Script || element.type == ElementType.style) + this.parseAttribs(element); + } + + return(elements); +} + +//Takes an element and adds an "attribs" property for any element attributes found +Parser.prototype.parseAttribs = function Parser$parseAttribs (element) { + //Only parse attributes for tags + if (element.type != ElementType.Script && element.type != ElementType.Style && element.type != ElementType.Tag) + return; + + var tagName = element.data.split(Parser._reWhitespace, 1)[0]; + var attribRaw = element.data.substring(tagName.length); + if (attribRaw.length < 1) + return; + + var match; + Parser._reAttrib.lastIndex = 0; + while (match = Parser._reAttrib.exec(attribRaw)) { + if (element.attribs == undefined) + element.attribs = {}; + + if (typeof match[1] == "string" && match[1].length) { + element.attribs[match[1]] = match[2]; + } else if (typeof match[3] == "string" && match[3].length) { + element.attribs[match[3].toString()] = match[4].toString(); + } else if (typeof match[5] == "string" && match[5].length) { + element.attribs[match[5]] = match[6]; + } else if (typeof match[7] == "string" && match[7].length) { + element.attribs[match[7]] = match[7]; + } + } +} + +//Extracts the base tag name from the data value of an element +Parser.prototype.parseTagName = function Parser$parseTagName (data) { + if (data == null || data == "") + return(""); + var match = Parser._reTagName.exec(data); + if (!match) + return(""); + return((match[1] ? "/" : "") + match[2]); +} + +//Parses through HTML text and returns an array of found elements +//I admit, this function is rather large but splitting up had an noticeable impact on speed +Parser.prototype.parseTags = function Parser$parseTags () { + var bufferEnd = this._buffer.length - 1; + while (Parser._reTags.test(this._buffer)) { + this._next = Parser._reTags.lastIndex - 1; + var tagSep = this._buffer.charAt(this._next); //The currently found tag marker + var rawData = this._buffer.substring(this._current, this._next); //The next chunk of data to parse + + //A new element to eventually be appended to the element list + var element = { + raw: rawData + , data: (this._parseState == ElementType.Text) ? rawData : rawData.replace(Parser._reTrim, "") + , type: this._parseState + }; + + var elementName = this.parseTagName(element.data); + + //This section inspects the current tag stack and modifies the current + //element if we're actually parsing a special area (script/comment/style tag) + if (this._tagStack.length) { //We're parsing inside a script/comment/style tag + if (this._tagStack[this._tagStack.length - 1] == ElementType.Script) { //We're currently in a script tag + if (elementName == "/script") //Actually, we're no longer in a script tag, so pop it off the stack + this._tagStack.pop(); + else { //Not a closing script tag + if (element.raw.indexOf("!--") != 0) { //Make sure we're not in a comment + //All data from here to script close is now a text element + element.type = ElementType.Text; + //If the previous element is text, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Text) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep + element.raw; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + } + } + } + } + else if (this._tagStack[this._tagStack.length - 1] == ElementType.Style) { //We're currently in a style tag + if (elementName == "/style") //Actually, we're no longer in a style tag, so pop it off the stack + this._tagStack.pop(); + else { + if (element.raw.indexOf("!--") != 0) { //Make sure we're not in a comment + //All data from here to style close is now a text element + element.type = ElementType.Text; + //If the previous element is text, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Text) { + if (element.raw != "") { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep + element.raw; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + } + else{ //Element is empty, so just append the last tag marker found + if (prevElement) { + prevElement.raw = prevElement.data = prevElement.raw + this._prevTagSep; + } + } + } + else //The previous element was not text + if (element.raw != "") + element.raw = element.data = element.raw; + } + } + } + else if (this._tagStack[this._tagStack.length - 1] == ElementType.Comment) { //We're currently in a comment tag + var rawLen = element.raw.length; + if (element.raw.charAt(rawLen - 2) == "-" && element.raw.charAt(rawLen - 1) == "-" && tagSep == ">") { + //Actually, we're no longer in a style tag, so pop it off the stack + this._tagStack.pop(); + //If the previous element is a comment, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Comment) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = (prevElement.raw + element.raw).replace(Parser._reTrimComment, ""); + element.raw = element.data = ""; //This causes the current element to not be added to the element list + element.type = ElementType.Text; + } + else //Previous element not a comment + element.type = ElementType.Comment; //Change the current element's type to a comment + } + else { //Still in a comment tag + element.type = ElementType.Comment; + //If the previous element is a comment, append the current text to it + if (this._elements.length && this._elements[this._elements.length - 1].type == ElementType.Comment) { + var prevElement = this._elements[this._elements.length - 1]; + prevElement.raw = prevElement.data = prevElement.raw + element.raw + tagSep; + element.raw = element.data = ""; //This causes the current element to not be added to the element list + element.type = ElementType.Text; + } + else + element.raw = element.data = element.raw + tagSep; + } + } + } + + //Processing of non-special tags + if (element.type == ElementType.Tag) { + element.name = elementName; + + if (element.raw.indexOf("!--") == 0) { //This tag is really comment + element.type = ElementType.Comment; + delete element["name"]; + var rawLen = element.raw.length; + //Check if the comment is terminated in the current element + if (element.raw.charAt(rawLen - 1) == "-" && element.raw.charAt(rawLen - 2) == "-" && tagSep == ">") + element.raw = element.data = element.raw.replace(Parser._reTrimComment, ""); + else { //It's not so push the comment onto the tag stack + element.raw += tagSep; + this._tagStack.push(ElementType.Comment); + } + } + else if (element.raw.indexOf("!") == 0 || element.raw.indexOf("?") == 0) { + element.type = ElementType.Directive; + //TODO: what about CDATA? + } + else if (element.name == "script") { + element.type = ElementType.Script; + //Special tag, push onto the tag stack if not terminated + if (element.data.charAt(element.data.length - 1) != "/") + this._tagStack.push(ElementType.Script); + } + else if (element.name == "/script") + element.type = ElementType.Script; + else if (element.name == "style") { + element.type = ElementType.Style; + //Special tag, push onto the tag stack if not terminated + if (element.data.charAt(element.data.length - 1) != "/") + this._tagStack.push(ElementType.Style); + } + else if (element.name == "/style") + element.type = ElementType.Style; + if (element.name && element.name.charAt(0) == "/") + element.data = element.name; + } + + //Add all tags and non-empty text elements to the element list + if (element.raw != "" || element.type != ElementType.Text) { + this.parseAttribs(element); + this._elements.push(element); + //If tag self-terminates, add an explicit, separate closing tag + if ( + element.type != ElementType.Text + && + element.type != ElementType.Comment + && + element.type != ElementType.Directive + && + element.data.charAt(element.data.length - 1) == "/" + ) + this._elements.push({ + raw: "/" + element.name + , data: "/" + element.name + , name: "/" + element.name + , type: element.type + }); + } + this._parseState = (tagSep == "<") ? ElementType.Tag : ElementType.Text; + this._current = this._next + 1; + this._prevTagSep = tagSep; + } + + this._buffer = (this._current <= bufferEnd) ? this._buffer.substring(this._current) : ""; + this._current = 0; + + this.writeHandler(); +} + +//Checks the handler to make it is an object with the right "interface" +Parser.prototype.validateHandler = function Parser$validateHandler (handler) { + if ((typeof handler) != "object") + throw new Error("Handler is not an object"); + if ((typeof handler.reset) != "function") + throw new Error("Handler method 'reset' is invalid"); + if ((typeof handler.done) != "function") + throw new Error("Handler method 'done' is invalid"); + if ((typeof handler.writeTag) != "function") + throw new Error("Handler method 'writeTag' is invalid"); + if ((typeof handler.writeText) != "function") + throw new Error("Handler method 'writeText' is invalid"); + if ((typeof handler.writeComment) != "function") + throw new Error("Handler method 'writeComment' is invalid"); + if ((typeof handler.writeDirective) != "function") + throw new Error("Handler method 'writeDirective' is invalid"); +} + +//Writes parsed elements out to the handler +Parser.prototype.writeHandler = function Parser$writeHandler (forceFlush) { + forceFlush = !!forceFlush; + if (this._tagStack.length && !forceFlush) + return; + while (this._elements.length) { + var element = this._elements.shift(); + switch (element.type) { + case ElementType.Comment: + this._handler.writeComment(element); + break; + case ElementType.Directive: + this._handler.writeDirective(element); + break; + case ElementType.Text: + this._handler.writeText(element); + break; + default: + this._handler.writeTag(element); + break; + } + } +} + +Parser.prototype.handleError = function Parser$handleError (error) { + if ((typeof this._handler.error) == "function") + this._handler.error(error); + else + throw error; +} + +//TODO: make this a trully streamable handler +function RssHandler (callback) { + RssHandler.super_.call(this, callback, { ignoreWhitespace: true, verbose: false, enforceEmptyTags: false }); +} +inherits(RssHandler, DefaultHandler); + +RssHandler.prototype.done = function RssHandler$done () { + var feed = { }; + var feedRoot; + + var found = DomUtils.getElementsByTagName(function (value) { return(value == "rss" || value == "feed"); }, this.dom, false); + if (found.length) { + feedRoot = found[0]; + } + if (feedRoot) { + if (feedRoot.name == "rss") { + feed.type = "rss"; + feedRoot = feedRoot.children[0]; // + feed.id = ""; + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("description", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("lastBuildDate", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("managingEditor", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("item", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("guid", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("description", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("pubDate", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } else { + feed.type = "atom"; + try { + feed.id = DomUtils.getElementsByTagName("id", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].attribs.href; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("subtitle", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("updated", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("email", feedRoot.children, true)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("entry", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("id", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].attribs.href; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("summary", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("updated", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } + + this.dom = feed; + } + RssHandler.super_.prototype.done.call(this); +} + +/////////////////////////////////////////////////// + +function DefaultHandler (callback, options) { + this.reset(); + this._options = options ? options : { }; + if (this._options.ignoreWhitespace == undefined) + this._options.ignoreWhitespace = false; //Keep whitespace-only text nodes + if (this._options.verbose == undefined) + this._options.verbose = true; //Keep data property for tags and raw property for all + if (this._options.enforceEmptyTags == undefined) + this._options.enforceEmptyTags = true; //Don't allow children for HTML tags defined as empty in spec + if ((typeof callback) == "function") + this._callback = callback; +} + +//**"Static"**// +//HTML Tags that shouldn't contain child nodes +DefaultHandler._emptyTags = { + area: 1 + , base: 1 + , basefont: 1 + , br: 1 + , col: 1 + , frame: 1 + , hr: 1 + , img: 1 + , input: 1 + , isindex: 1 + , link: 1 + , meta: 1 + , param: 1 + , embed: 1 +} +//Regex to detect whitespace only text nodes +DefaultHandler.reWhitespace = /^\s*$/; + +//**Public**// +//Properties// +DefaultHandler.prototype.dom = null; //The hierarchical object containing the parsed HTML +//Methods// +//Resets the handler back to starting state +DefaultHandler.prototype.reset = function DefaultHandler$reset() { + this.dom = []; + this._done = false; + this._tagStack = []; + this._tagStack.last = function DefaultHandler$_tagStack$last () { + return(this.length ? this[this.length - 1] : null); + } +} +//Signals the handler that parsing is done +DefaultHandler.prototype.done = function DefaultHandler$done () { + this._done = true; + this.handleCallback(null); +} +DefaultHandler.prototype.writeTag = function DefaultHandler$writeTag (element) { + this.handleElement(element); +} +DefaultHandler.prototype.writeText = function DefaultHandler$writeText (element) { + if (this._options.ignoreWhitespace) + if (DefaultHandler.reWhitespace.test(element.data)) + return; + this.handleElement(element); +} +DefaultHandler.prototype.writeComment = function DefaultHandler$writeComment (element) { + this.handleElement(element); +} +DefaultHandler.prototype.writeDirective = function DefaultHandler$writeDirective (element) { + this.handleElement(element); +} +DefaultHandler.prototype.error = function DefaultHandler$error (error) { + this.handleCallback(error); +} + +//**Private**// +//Properties// +DefaultHandler.prototype._options = null; //Handler options for how to behave +DefaultHandler.prototype._callback = null; //Callback to respond to when parsing done +DefaultHandler.prototype._done = false; //Flag indicating whether handler has been notified of parsing completed +DefaultHandler.prototype._tagStack = null; //List of parents to the currently element being processed +//Methods// +DefaultHandler.prototype.handleCallback = function DefaultHandler$handleCallback (error) { + if ((typeof this._callback) != "function") + if (error) + throw error; + else + return; + this._callback(error, this.dom); +} +DefaultHandler.prototype.handleElement = function DefaultHandler$handleElement (element) { + if (this._done) + this.handleCallback(new Error("Writing to the handler after done() called is not allowed without a reset()")); + if (!this._options.verbose) { + // element.raw = null; //FIXME: Not clean + //FIXME: Serious performance problem using delete + delete element.raw; + if (element.type == "tag" || element.type == "script" || element.type == "style") + delete element.data; + } + if (!this._tagStack.last()) { //There are no parent elements + //If the element can be a container, add it to the tag stack and the top level list + if (element.type != ElementType.Text && element.type != ElementType.Comment && element.type != ElementType.Directive) { + if (element.name.charAt(0) != "/") { //Ignore closing tags that obviously don't have an opening tag + this.dom.push(element); + if (!this._options.enforceEmptyTags || !DefaultHandler._emptyTags[element.name]) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(element); + } + } + } + else //Otherwise just add to the top level list + this.dom.push(element); + } + else { //There are parent elements + //If the element can be a container, add it as a child of the element + //on top of the tag stack and then add it to the tag stack + if (element.type != ElementType.Text && element.type != ElementType.Comment && element.type != ElementType.Directive) { + if (element.name.charAt(0) == "/") { + //This is a closing tag, scan the tagStack to find the matching opening tag + //and pop the stack up to the opening tag's parent + var baseName = element.name.substring(1); + if (!this._options.enforceEmptyTags || !DefaultHandler._emptyTags[baseName]) { + var pos = this._tagStack.length - 1; + while (pos > -1 && this._tagStack[pos--].name != baseName) { } + if (pos > -1 || this._tagStack[0].name == baseName) + while (pos < this._tagStack.length - 1) + this._tagStack.pop(); + } + } + else { //This is not a closing tag + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(element); + if (!this._options.enforceEmptyTags || !DefaultHandler._emptyTags[element.name]) //Don't add tags to the tag stack that can't have children + this._tagStack.push(element); + } + } + else { //This is not a container element + if (!this._tagStack.last().children) + this._tagStack.last().children = []; + this._tagStack.last().children.push(element); + } + } +} + +var DomUtils = { + testElement: function DomUtils$testElement (options, element) { + if (!element) { + return false; + } + + for (var key in options) { + if (key == "tag_name") { + if (element.type != "tag" && element.type != "script" && element.type != "style") { + return false; + } + if (!options["tag_name"](element.name)) { + return false; + } + } else if (key == "tag_type") { + if (!options["tag_type"](element.type)) { + return false; + } + } else if (key == "tag_contains") { + if (element.type != "text" && element.type != "comment" && element.type != "directive") { + return false; + } + if (!options["tag_contains"](element.data)) { + return false; + } + } else { + if (!element.attribs || !options[key](element.attribs[key])) { + return false; + } + } + } + + return true; + } + + , getElements: function DomUtils$getElements (options, currentElement, recurse, limit) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + limit = isNaN(parseInt(limit)) ? -1 : parseInt(limit); + + if (!currentElement) { + return([]); + } + + var found = []; + var elementList; + + function getTest (checkVal) { + return(function (value) { return(value == checkVal); }); + } + for (var key in options) { + if ((typeof options[key]) != "function") { + options[key] = getTest(options[key]); + } + } + + if (DomUtils.testElement(options, currentElement)) { + found.push(currentElement); + } + + if (limit >= 0 && found.length >= limit) { + return(found); + } + + if (recurse && currentElement.children) { + elementList = currentElement.children; + } else if (currentElement instanceof Array) { + elementList = currentElement; + } else { + return(found); + } + + for (var i = 0; i < elementList.length; i++) { + found = found.concat(DomUtils.getElements(options, elementList[i], recurse, limit)); + if (limit >= 0 && found.length >= limit) { + break; + } + } + + return(found); + } + + , getElementById: function DomUtils$getElementById (id, currentElement, recurse) { + var result = DomUtils.getElements({ id: id }, currentElement, recurse, 1); + return(result.length ? result[0] : null); + } + + , getElementsByTagName: function DomUtils$getElementsByTagName (name, currentElement, recurse, limit) { + return(DomUtils.getElements({ tag_name: name }, currentElement, recurse, limit)); + } + + , getElementsByTagType: function DomUtils$getElementsByTagType (type, currentElement, recurse, limit) { + return(DomUtils.getElements({ tag_type: type }, currentElement, recurse, limit)); + } +} + +function inherits (ctor, superCtor) { + var tempCtor = function(){}; + tempCtor.prototype = superCtor.prototype; + ctor.super_ = superCtor; + ctor.prototype = new tempCtor(); + ctor.prototype.constructor = ctor; +} + +exports.Parser = Parser; + +exports.DefaultHandler = DefaultHandler; + +exports.RssHandler = RssHandler; + +exports.ElementType = ElementType; + +exports.DomUtils = DomUtils; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/lib/node-htmlparser.min.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/lib/node-htmlparser.min.js new file mode 100644 index 0000000..5ab1e72 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/lib/node-htmlparser.min.js @@ -0,0 +1,22 @@ +/*********************************************** +Copyright 2010, Chris Winberry . All rights reserved. +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. +***********************************************/ +/* v1.6.3 */ +(function(){function e(a){this.validateHandler(a);this._handler=a;this.reset()}function n(a){n.super_.call(this,a,{ignoreWhitespace:true,verbose:false,enforceEmptyTags:false})}function g(a,c){this.reset();this._options=c?c:{};if(this._options.ignoreWhitespace==undefined)this._options.ignoreWhitespace=false;if(this._options.verbose==undefined)this._options.verbose=true;if(this._options.enforceEmptyTags==undefined)this._options.enforceEmptyTags=true;if(typeof a=="function")this._callback=a}if(!(typeof require== "function"&&typeof exports=="object"&&typeof module=="object"&&typeof __filename=="string"&&typeof __dirname=="string")){if(this.Tautologistics){if(this.Tautologistics.NodeHtmlParser)return}else this.Tautologistics={};this.Tautologistics.NodeHtmlParser={};exports=this.Tautologistics.NodeHtmlParser}var d={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag"};e._reTrim=/(^\s+|\s+$)/g;e._reTrimComment=/(^\!--|--$)/g;e._reWhitespace=/\s/g;e._reTagName=/^\s*(\/?)\s*([^\s\/]+)/; e._reAttrib=/([^=<>\"\'\s]+)\s*=\s*"([^"]*)"|([^=<>\"\'\s]+)\s*=\s*'([^']*)'|([^=<>\"\'\s]+)\s*=\s*([^'"\s]+)|([^=<>\"\'\s\/]+)/g;e._reTags=/[\<\>]/g;e.prototype.parseComplete=function(a){this.reset();this.parseChunk(a);this.done()};e.prototype.parseChunk=function(a){this._done&&this.handleError(Error("Attempted to parse chunk after parsing already done"));this._buffer+=a;this.parseTags()};e.prototype.done=function(){if(!this._done){this._done=true;if(this._buffer.length){var a=this._buffer;this._buffer= "";a={raw:a,data:this._parseState==d.Text?a:a.replace(e._reTrim,""),type:this._parseState};if(this._parseState==d.Tag||this._parseState==d.Script||this._parseState==d.Style)a.name=this.parseTagName(a.data);this.parseAttribs(a);this._elements.push(a)}this.writeHandler();this._handler.done()}};e.prototype.reset=function(){this._buffer="";this._done=false;this._elements=[];this._next=this._current=this._elementsCurrent=0;this._parseState=d.Text;this._prevTagSep="";this._tagStack=[];this._handler.reset()}; e.prototype._handler=null;e.prototype._buffer=null;e.prototype._done=false;e.prototype._elements=null;e.prototype._elementsCurrent=0;e.prototype._current=0;e.prototype._next=0;e.prototype._parseState=d.Text;e.prototype._prevTagSep="";e.prototype._tagStack=null;e.prototype.parseTagAttribs=function(a){for(var c=a.length,b=0;b"){this._tagStack.pop();if(this._elements.length&&this._elements[this._elements.length-1].type==d.Comment){i=this._elements[this._elements.length-1];i.raw=i.data=(i.raw+b.raw).replace(e._reTrimComment, "");b.raw=b.data="";b.type=d.Text}else b.type=d.Comment}else{b.type=d.Comment;if(this._elements.length&&this._elements[this._elements.length-1].type==d.Comment){i=this._elements[this._elements.length-1];i.raw=i.data=i.raw+b.raw+c;b.raw=b.data="";b.type=d.Text}else b.raw=b.data=b.raw+c}}if(b.type==d.Tag){b.name=h;if(b.raw.indexOf("!--")==0){b.type=d.Comment;delete b.name;j=b.raw.length;if(b.raw.charAt(j-1)=="-"&&b.raw.charAt(j-2)=="-"&&c==">")b.raw=b.data=b.raw.replace(e._reTrimComment,"");else{b.raw+= c;this._tagStack.push(d.Comment)}}else if(b.raw.indexOf("!")==0||b.raw.indexOf("?")==0)b.type=d.Directive;else if(b.name=="script"){b.type=d.Script;b.data.charAt(b.data.length-1)!="/"&&this._tagStack.push(d.Script)}else if(b.name=="/script")b.type=d.Script;else if(b.name=="style"){b.type=d.Style;b.data.charAt(b.data.length-1)!="/"&&this._tagStack.push(d.Style)}else if(b.name=="/style")b.type=d.Style;if(b.name&&b.name.charAt(0)=="/")b.data=b.name}if(b.raw!=""||b.type!=d.Text){this.parseAttribs(b); this._elements.push(b);b.type!=d.Text&&b.type!=d.Comment&&b.type!=d.Directive&&b.data.charAt(b.data.length-1)=="/"&&this._elements.push({raw:"/"+b.name,data:"/"+b.name,name:"/"+b.name,type:b.type})}this._parseState=c=="<"?d.Tag:d.Text;this._current=this._next+1;this._prevTagSep=c}this._buffer=this._current<=a?this._buffer.substring(this._current):"";this._current=0;this.writeHandler()};e.prototype.validateHandler=function(a){if(typeof a!="object")throw Error("Handler is not an object");if(typeof a.reset!= "function")throw Error("Handler method 'reset' is invalid");if(typeof a.done!="function")throw Error("Handler method 'done' is invalid");if(typeof a.writeTag!="function")throw Error("Handler method 'writeTag' is invalid");if(typeof a.writeText!="function")throw Error("Handler method 'writeText' is invalid");if(typeof a.writeComment!="function")throw Error("Handler method 'writeComment' is invalid");if(typeof a.writeDirective!="function")throw Error("Handler method 'writeDirective' is invalid");}; e.prototype.writeHandler=function(a){a=!!a;if(!(this._tagStack.length&&!a))for(;this._elements.length;){a=this._elements.shift();switch(a.type){case d.Comment:this._handler.writeComment(a);break;case d.Directive:this._handler.writeDirective(a);break;case d.Text:this._handler.writeText(a);break;default:this._handler.writeTag(a)}}};e.prototype.handleError=function(a){if(typeof this._handler.error=="function")this._handler.error(a);else throw a;};(function(a,c){var b=function(){};b.prototype=c.prototype; a.super_=c;a.prototype=new b;a.prototype.constructor=a})(n,g);n.prototype.done=function(){var a={},c,b=f.getElementsByTagName(function(k){return k=="rss"||k=="feed"},this.dom,false);if(b.length)c=b[0];if(c){if(c.name=="rss"){a.type="rss";c=c.children[0];a.id="";try{a.title=f.getElementsByTagName("title",c.children,false)[0].children[0].data}catch(h){}try{a.link=f.getElementsByTagName("link",c.children,false)[0].children[0].data}catch(i){}try{a.description=f.getElementsByTagName("description",c.children, false)[0].children[0].data}catch(j){}try{a.updated=new Date(f.getElementsByTagName("lastBuildDate",c.children,false)[0].children[0].data)}catch(m){}try{a.author=f.getElementsByTagName("managingEditor",c.children,false)[0].children[0].data}catch(o){}a.items=[];f.getElementsByTagName("item",c.children).forEach(function(k){var l={};try{l.id=f.getElementsByTagName("guid",k.children,false)[0].children[0].data}catch(q){}try{l.title=f.getElementsByTagName("title",k.children,false)[0].children[0].data}catch(r){}try{l.link= f.getElementsByTagName("link",k.children,false)[0].children[0].data}catch(s){}try{l.description=f.getElementsByTagName("description",k.children,false)[0].children[0].data}catch(t){}try{l.pubDate=new Date(f.getElementsByTagName("pubDate",k.children,false)[0].children[0].data)}catch(u){}a.items.push(l)})}else{a.type="atom";try{a.id=f.getElementsByTagName("id",c.children,false)[0].children[0].data}catch(p){}try{a.title=f.getElementsByTagName("title",c.children,false)[0].children[0].data}catch(v){}try{a.link= f.getElementsByTagName("link",c.children,false)[0].attribs.href}catch(w){}try{a.description=f.getElementsByTagName("subtitle",c.children,false)[0].children[0].data}catch(x){}try{a.updated=new Date(f.getElementsByTagName("updated",c.children,false)[0].children[0].data)}catch(y){}try{a.author=f.getElementsByTagName("email",c.children,true)[0].children[0].data}catch(z){}a.items=[];f.getElementsByTagName("entry",c.children).forEach(function(k){var l={};try{l.id=f.getElementsByTagName("id",k.children, false)[0].children[0].data}catch(q){}try{l.title=f.getElementsByTagName("title",k.children,false)[0].children[0].data}catch(r){}try{l.link=f.getElementsByTagName("link",k.children,false)[0].attribs.href}catch(s){}try{l.description=f.getElementsByTagName("summary",k.children,false)[0].children[0].data}catch(t){}try{l.pubDate=new Date(f.getElementsByTagName("updated",k.children,false)[0].children[0].data)}catch(u){}a.items.push(l)})}this.dom=a}n.super_.prototype.done.call(this)};g._emptyTags={area:1, base:1,basefont:1,br:1,col:1,frame:1,hr:1,img:1,input:1,isindex:1,link:1,meta:1,param:1,embed:1};g.reWhitespace=/^\s*$/;g.prototype.dom=null;g.prototype.reset=function(){this.dom=[];this._done=false;this._tagStack=[];this._tagStack.last=function(){return this.length?this[this.length-1]:null}};g.prototype.done=function(){this._done=true;this.handleCallback(null)};g.prototype.writeTag=function(a){this.handleElement(a)};g.prototype.writeText=function(a){if(this._options.ignoreWhitespace)if(g.reWhitespace.test(a.data))return; this.handleElement(a)};g.prototype.writeComment=function(a){this.handleElement(a)};g.prototype.writeDirective=function(a){this.handleElement(a)};g.prototype.error=function(a){this.handleCallback(a)};g.prototype._options=null;g.prototype._callback=null;g.prototype._done=false;g.prototype._tagStack=null;g.prototype.handleCallback=function(a){if(typeof this._callback!="function")if(a)throw a;else return;this._callback(a,this.dom)};g.prototype.handleElement=function(a){this._done&&this.handleCallback(Error("Writing to the handler after done() called is not allowed without a reset()")); if(!this._options.verbose){delete a.raw;if(a.type=="tag"||a.type=="script"||a.type=="style")delete a.data}if(this._tagStack.last())if(a.type!=d.Text&&a.type!=d.Comment&&a.type!=d.Directive)if(a.name.charAt(0)=="/"){a=a.name.substring(1);if(!this._options.enforceEmptyTags||!g._emptyTags[a]){for(var c=this._tagStack.length-1;c>-1&&this._tagStack[c--].name!=a;);if(c>-1||this._tagStack[0].name==a)for(;c=0&&j.length>=h)return j;if(b&&c.children)c=c.children;else if(c instanceof Array)c=c;else return j;for(m=0;m=0&&j.length>=h)break}return j},getElementById:function(a,c,b){a=f.getElements({id:a},c,b,1);return a.length?a[0]:null},getElementsByTagName:function(a,c,b,h){return f.getElements({tag_name:a},c,b,h)},getElementsByTagType:function(a, c,b,h){return f.getElements({tag_type:a},c,b,h)}};exports.Parser=e;exports.DefaultHandler=g;exports.RssHandler=n;exports.ElementType=d;exports.DomUtils=f})(); \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/package.json b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/package.json new file mode 100644 index 0000000..ced4c0a --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/package.json @@ -0,0 +1,23 @@ +{ + "name": "htmlparser" + , "description": "Forgiving HTML/XML/RSS Parser in JS for *both* Node and Browsers" + , "version": "1.6.2" + , "author": "Chris Winberry " + , "contributors": [] + , "repository": { + "type": "git" + , "url": "git://github.com/tautologistics/node-htmlparser.git" + } + , "bugs": { + "mail": "chris@winberry.net" + , "web": "http://github.com/tautologistics/node-htmlparser/issues" + } + , "os": [ "linux", "darwin", "freebsd" ] + , "directories": { "lib": "./lib/" } + , "main": "./lib/node-htmlparser" + , "engines": { "node": ">=0.1.33" } + , "licenses": [{ + "type": "MIT" + , "url": "http://github.com/tautologistics/node-htmlparser/raw/master/LICENSE" + }] +} diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/profile.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/profile.js new file mode 100644 index 0000000..c5a474e --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/profile.js @@ -0,0 +1,63 @@ +//node --prof --prof_auto profile.js +//deps/v8/tools/mac-tick-processor v8.log +var sys = require("sys"); +var fs = require("fs"); +var http = require("http"); +var htmlparser = require("./node-htmlparser"); +var libxml = require('./libxmljs'); + +var testNHP = true; //Should node-htmlparser be exercised? +var testLXJS = true; //Should libxmljs be exercised? +var testIterations = 100; //Number of test loops to run + +var testHost = "nodejs.org"; //Host to fetch test HTML from +var testPort = 80; //Port on host to fetch test HTML from +var testPath = "/api.html"; //Path on host to fetch HTML from + +function getMillisecs () { + return((new Date()).getTime()); +} + +function timeExecutions (loops, func) { + var start = getMillisecs(); + + while (loops--) + func(); + + return(getMillisecs() - start); +} + +var html = ""; +http.createClient(testPort, testHost) + .request("GET", testPath, { host: testHost }) + .addListener("response", function (response) { + if (response.statusCode == "200") { + response.setEncoding("utf8"); + response.addListener("data", function (chunk) { + html += chunk; + }).addListener("end", function() { + var timeNodeHtmlParser = !testNHP ? 0 : timeExecutions(testIterations, function () { + var handler = new htmlparser.DefaultHandler(function(err, dom) { + if (err) + sys.debug("Error: " + err); + }); + var parser = new htmlparser.Parser(handler); + parser.parseComplete(html); + }) + + var timeLibXmlJs = !testLXJS ? 0 : timeExecutions(testIterations, function () { + var dom = libxml.parseHtmlString(html); + }) + + if (testNHP) + sys.debug("NodeHtmlParser: " + timeNodeHtmlParser); + if (testLXJS) + sys.debug("LibXmlJs: " + timeLibXmlJs); + if (testNHP && testLXJS) + sys.debug("Difference: " + ((timeNodeHtmlParser - timeLibXmlJs) / timeLibXmlJs) * 100); + }); + } + else + sys.debug("Error: got response status " + response.statusCode); + }) + .end(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.html b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.html new file mode 100644 index 0000000..3543adc --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.html @@ -0,0 +1,107 @@ + + + + + Node.js HTML Parser + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.js new file mode 100644 index 0000000..c59393c --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.js @@ -0,0 +1,75 @@ +/*********************************************** +Copyright 2010, Chris Winberry . All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +***********************************************/ + +var sys = require("sys"); +var fs = require("fs"); +var htmlparser = require("./lib/node-htmlparser"); + +var testFolder = "./tests"; +var chunkSize = 5; + +var testFiles = fs.readdirSync(testFolder); +var testCount = 0; +var failedCount = 0; +for (var i in testFiles) { + testCount++; + var fileParts = testFiles[i].split("."); + fileParts.pop(); + var moduleName = fileParts.join("."); + var test = require(testFolder + "/" + moduleName); + var handlerCallback = function handlerCallback (error) { + if (error) + sys.puts("Handler error: " + error); + } + var handler = (test.type == "rss") ? + new htmlparser.RssHandler(handlerCallback, test.options) + : + new htmlparser.DefaultHandler(handlerCallback, test.options) + ; + var parser = new htmlparser.Parser(handler); + parser.parseComplete(test.html); + var resultComplete = handler.dom; + var chunkPos = 0; + parser.reset(); + while (chunkPos < test.html.length) { + parser.parseChunk(test.html.substring(chunkPos, chunkPos + chunkSize)); + chunkPos += chunkSize; + } + parser.done(); + var resultChunk = handler.dom; + var testResult = + sys.inspect(resultComplete, false, null) === sys.inspect(test.expected, false, null) + && + sys.inspect(resultChunk, false, null) === sys.inspect(test.expected, false, null) + ; + sys.puts("[" + test.name + "\]: " + (testResult ? "passed" : "FAILED")); + if (!testResult) { + failedCount++; + sys.puts("== Complete =="); + sys.puts(sys.inspect(resultComplete, false, null)); + sys.puts("== Chunked =="); + sys.puts(sys.inspect(resultChunk, false, null)); + sys.puts("== Expected =="); + sys.puts(sys.inspect(test.expected, false, null)); + } +} +sys.puts("Total tests: " + testCount); +sys.puts("Failed tests: " + failedCount); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.html b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.html new file mode 100644 index 0000000..2ec9e8f --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.html @@ -0,0 +1,107 @@ + + + + + Node.js HTML Parser + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.js new file mode 100644 index 0000000..d32c3aa --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/runtests.min.js @@ -0,0 +1,75 @@ +/*********************************************** +Copyright 2010, Chris Winberry . All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +***********************************************/ + +var sys = require("sys"); +var fs = require("fs"); +var htmlparser = require("./lib/node-htmlparser.min"); + +var testFolder = "./tests"; +var chunkSize = 5; + +var testFiles = fs.readdirSync(testFolder); +var testCount = 0; +var failedCount = 0; +for (var i in testFiles) { + testCount++; + var fileParts = testFiles[i].split("."); + fileParts.pop(); + var moduleName = fileParts.join("."); + var test = require(testFolder + "/" + moduleName); + var handlerCallback = function handlerCallback (error) { + if (error) + sys.puts("Handler error: " + error); + } + var handler = (test.type == "rss") ? + new htmlparser.RssHandler(handlerCallback, test.options) + : + new htmlparser.DefaultHandler(handlerCallback, test.options) + ; + var parser = new htmlparser.Parser(handler); + parser.parseComplete(test.html); + var resultComplete = handler.dom; + var chunkPos = 0; + parser.reset(); + while (chunkPos < test.html.length) { + parser.parseChunk(test.html.substring(chunkPos, chunkPos + chunkSize)); + chunkPos += chunkSize; + } + parser.done(); + var resultChunk = handler.dom; + var testResult = + sys.inspect(resultComplete, false, null) === sys.inspect(test.expected, false, null) + && + sys.inspect(resultChunk, false, null) === sys.inspect(test.expected, false, null) + ; + sys.puts("[" + test.name + "\]: " + (testResult ? "passed" : "FAILED")); + if (!testResult) { + failedCount++; + sys.puts("== Complete =="); + sys.puts(sys.inspect(resultComplete, false, null)); + sys.puts("== Chunked =="); + sys.puts(sys.inspect(resultChunk, false, null)); + sys.puts("== Expected =="); + sys.puts(sys.inspect(test.expected, false, null)); + } +} +sys.puts("Total tests: " + testCount); +sys.puts("Failed tests: " + failedCount); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/snippet.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/snippet.js new file mode 100644 index 0000000..2f54b36 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/snippet.js @@ -0,0 +1,15 @@ +//node --prof --prof_auto profile.js +//deps/v8/tools/mac-tick-processor v8.log +var sys = require("sys"); +var htmlparser = require("./node-htmlparser"); + +var html = "text"; + +var handler = new htmlparser.DefaultHandler(function(err, dom) { + if (err) + sys.debug("Error: " + err); + else + sys.debug(sys.inspect(dom, false, null)); +}, { enforceEmptyTags: true }); +var parser = new htmlparser.Parser(handler); +parser.parseComplete(html); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/01-basic.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/01-basic.js new file mode 100644 index 0000000..57de7dc --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/01-basic.js @@ -0,0 +1,57 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Basic test"; +exports.html = "The TitleHello world"; +exports.expected = + [ { raw: 'html' + , data: 'html' + , type: 'tag' + , name: 'html' + , children: + [ { raw: 'title' + , data: 'title' + , type: 'tag' + , name: 'title' + , children: [ { raw: 'The Title', data: 'The Title', type: 'text' } ] + } + , { raw: 'body' + , data: 'body' + , type: 'tag' + , name: 'body' + , children: + [ { raw: 'Hello world' + , data: 'Hello world' + , type: 'text' + } + ] + } + ] + } + ]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/02-single_tag_1.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/02-single_tag_1.js new file mode 100644 index 0000000..8af04d9 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/02-single_tag_1.js @@ -0,0 +1,35 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Single Tag 1"; +exports.html = "
text
"; +exports.expected = + [ { raw: 'br', data: 'br', type: 'tag', name: 'br' } + , { raw: 'text', data: 'text', type: 'text' } + ]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/03-single_tag_2.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/03-single_tag_2.js new file mode 100644 index 0000000..beae642 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/03-single_tag_2.js @@ -0,0 +1,36 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Single Tag 2"; +exports.html = "
text
"; +exports.expected = + [ { raw: 'br', data: 'br', type: 'tag', name: 'br' } + , { raw: 'text', data: 'text', type: 'text' } + , { raw: 'br', data: 'br', type: 'tag', name: 'br' } + ]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/04-unescaped_in_script.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/04-unescaped_in_script.js new file mode 100644 index 0000000..1a23385 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/04-unescaped_in_script.js @@ -0,0 +1,52 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Unescaped chars in script"; +exports.html = ""; +exports.expected = +[ { raw: 'head' + , data: 'head' + , type: 'tag' + , name: 'head' + , children: + [ { raw: 'script language="Javascript"' + , data: 'script language="Javascript"' + , type: 'script' + , name: 'script' + , attribs: { language: 'Javascript' } + , children: + [ { raw: 'var foo = ""; alert(2 > foo); var baz = 10 << 2; var zip = 10 >> 1; var yap = \"<<>>>><<\";' + , data: 'var foo = ""; alert(2 > foo); var baz = 10 << 2; var zip = 10 >> 1; var yap = \"<<>>>><<\";' + , type: 'text' + } + ] + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/05-tags_in_comment.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/05-tags_in_comment.js new file mode 100644 index 0000000..79fdd8c --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/05-tags_in_comment.js @@ -0,0 +1,44 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Special char in comment"; +exports.html = ""; +exports.expected = +[ { raw: 'head' + , data: 'head' + , type: 'tag' + , name: 'head' + , children: + [ { raw: ' commented out tags Test' + , data: ' commented out tags Test' + , type: 'comment' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/06-comment_in_script.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/06-comment_in_script.js new file mode 100644 index 0000000..7737f38 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/06-comment_in_script.js @@ -0,0 +1,44 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Script source in comment"; +exports.html = ""; +exports.expected = +[ { raw: 'script' + , data: 'script' + , type: 'script' + , name: 'script' + , children: + [ { raw: 'var foo = 1;' + , data: 'var foo = 1;' + , type: 'comment' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/07-unescaped_in_style.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/07-unescaped_in_style.js new file mode 100644 index 0000000..fe4efad --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/07-unescaped_in_style.js @@ -0,0 +1,45 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Unescaped chars in style"; +exports.html = ""; +exports.expected = +[ { raw: 'style type="text/css"' + , data: 'style type="text/css"' + , type: 'style' + , name: 'style' + , attribs: { type: 'text/css' } + , children: + [ { raw: '\n body > p\n { font-weight: bold; }' + , data: '\n body > p\n { font-weight: bold; }' + , type: 'text' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/08-extra_spaces_in_tag.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/08-extra_spaces_in_tag.js new file mode 100644 index 0000000..84192af --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/08-extra_spaces_in_tag.js @@ -0,0 +1,45 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Extra spaces in tag"; +exports.html = "<\n font \n size='14' \n>the text<\n / \nfont \n>"; +exports.expected = +[ { raw: '\n font \n size=\'14\' \n' + , data: 'font \n size=\'14\'' + , type: 'tag' + , name: 'font' + , attribs: { size: '14' } + , children: + [ { raw: 'the text' + , data: 'the text' + , type: 'text' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/09-unquoted_attrib.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/09-unquoted_attrib.js new file mode 100644 index 0000000..3ad54e6 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/09-unquoted_attrib.js @@ -0,0 +1,45 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Unquoted attributes"; +exports.html = "the text"; +exports.expected = +[ { raw: 'font size= 14' + , data: 'font size= 14' + , type: 'tag' + , name: 'font' + , attribs: { size: '14' } + , children: + [ { raw: 'the text' + , data: 'the text' + , type: 'text' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/10-singular_attribute.js b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/10-singular_attribute.js new file mode 100644 index 0000000..37897dc --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/pulls/node-htmlparser/tests/10-singular_attribute.js @@ -0,0 +1,39 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Singular attribute"; +exports.html = "
+ + + + + + diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.76922~ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.76922~ new file mode 100644 index 0000000..b499243 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.76922~ @@ -0,0 +1,10 @@ + + + + +Insert title here + + + + + \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.80022~ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.80022~ new file mode 100644 index 0000000..e000284 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker.html.80022~ @@ -0,0 +1,2948 @@ + + + +www.trackerchecker.com - We check your trackers + + + + + + +
+ + + + + + + +
Home || Add a tracker || Latest trackers
+
+ + +
+follow us on Twitter
+Follow trackerchecker on Twitter --> @trackerchecker. +
+ +
+ + +
+
+ TrackerList
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 TrackerNameHistoryLastCheckedStatus
1337x.orgview history2010-03-29 03:56:03Open
420project.orgview history2010-03-29 04:28:13Closed
acehd.netview history2010-03-29 04:31:58Closed
acetorrents.netview history2010-03-29 03:59:08Open
adult-cinema-network.netview history2010-03-29 04:00:08Open
all4nothin.netview history2010-03-29 04:01:08Open
allgirltorrents.comview history2010-03-29 03:50:57Closed
allotracker.comview history2010-03-29 03:58:09Open
appz.bitshock.orgview history2010-03-29 03:57:12Open
appzuniverse.orgview history2010-03-29 04:18:04Closed
arabfilms.orgview history2010-03-29 04:08:50Closed
arabseries.orgview history2010-03-29 03:59:39Closed
araditracker.comview history2010-03-29 04:22:25Closed
arena-tr.comview history2010-03-29 04:12:10Closed
arenabg.comview history2010-03-29 03:51:00Closed
artofmisdirection.comview history2010-03-29 04:01:04Closed
asiandvdclub.orgview history2010-03-29 04:18:15Open
at-tracker.orgview history2010-03-29 04:15:08Offline
atomico-torrent.comview history2010-03-29 03:56:05Closed
audionews.ruview history2010-03-29 04:01:02Closed
audiotracer.comview history2010-03-29 04:05:08Closed
audiozonetorrents.comview history2010-03-29 03:56:09Open
avatarbg.infoview history2010-03-29 03:49:14Closed
awesome-hd.comview history2010-03-29 03:51:07Closed
awesome-hd.netview history2010-03-29 03:55:09Closed
baltracker.netview history2010-03-29 04:15:09Open
bestmmatorrents.comview history2010-03-29 04:15:04Closed
bestshare.roview history2010-03-29 03:56:11Closed
bestxvid.orgview history2010-03-29 03:50:57Closed
bit-hdtv.comview history2010-03-29 03:58:10Closed
bitaddict.orgview history2010-03-29 03:50:45Closed
bitchil.comview history2010-03-29 03:56:09Open
bitflamers.comview history2010-03-29 04:01:12Closed
bitgamer.comview history2010-03-29 04:12:08Closed
bithq.orgview history2010-03-29 03:58:08Open
bithumen.ath.cxview history2010-03-29 04:22:20Closed
bitlove.huview history2010-03-29 04:25:10Closed
bitme.orgview history2010-03-29 04:12:06Closed
bitmetv.orgview history2010-03-29 03:49:16Closed
bitmusic.huview history2010-03-29 03:58:11Closed
bitnation.comview history2010-03-29 03:59:08Closed
bitseduce.comview history2010-03-29 04:05:08Closed
bitseek.orgview history2010-03-29 04:28:05Closed
bitseek.orgview history2010-03-29 04:18:05Closed
bitshock.orgview history2010-03-29 04:00:03Open
bitshock.orgview history2010-03-29 03:55:14Closed
bitsoup.orgview history2010-03-29 03:59:07Open
bitSpyder.netview history2010-03-29 03:56:06Closed
bittorrents.roview history2010-03-29 04:00:14Closed
bitturk.netview history2010-03-29 03:56:05Closed
biztorrents.comview history2010-03-29 04:15:07Open
blackcats-games.netview history2010-03-29 03:58:06Closed
blades-heaven.comview history2010-03-29 04:08:56Open
blue-bytez.comview history2010-03-29 04:32:01Closed
blue-whitegt.comview history2010-03-29 04:28:13Closed
bmtorrents.netview history2010-03-29 03:58:10Closed
bootytape.comview history2010-03-29 03:58:02Open
bootytorrents.comview history2010-03-29 03:57:07Closed
boxtorrents.comview history2010-03-29 04:08:59Closed
bt.avistaz.comview history2010-03-29 04:15:08Closed
bt.davka.infoview history2010-03-29 04:08:50Open
bt.xbox-sky.ccview history2010-03-29 03:49:08Closed
bt.xbox-sky.comview history2010-03-29 03:50:42Closed
btgigs.infoview history2010-03-29 04:18:15Closed
bwtorrents.comview history2010-03-29 03:56:10Closed
bytelist.orgview history2010-03-29 04:05:07Offline
cartoonchaos.orgview history2010-03-29 04:18:15Closed
ccfbits.orgview history2010-03-29 04:22:19Closed
chdbits.orgview history2010-03-29 04:15:11Closed
cheggit.net/view history2010-03-29 04:09:00Open
chilebt.comview history2010-03-29 04:22:11Closed
christiantorrents.comview history2010-03-29 04:28:13Closed
chronictracker.comview history2010-03-29 04:01:13Closed
cinema-obscura.comview history2010-03-29 03:57:06Closed
cinemageddon.orgview history2010-03-29 04:22:27Closed
cinematik.netview history2010-03-29 03:57:11Closed
cleanvobs.orgview history2010-03-29 03:49:43Closed
colombo-bt.orgview history2010-03-29 03:50:55Closed
contego.wsview history2010-03-29 04:22:12Closed
crazytorrent.euview history2010-03-29 04:08:49Closed
czone.roview history2010-03-29 04:24:09Closed
danger.lvview history2010-03-29 03:55:15Closed
demonoid.comview history2010-03-29 04:18:15Closed
devilwolfs.comview history2010-03-29 04:31:55Closed
diablotorrent.huview history2010-03-29 03:56:01Closed
dididave.comview history2010-03-29 04:00:03Closed
digitalhive.orgview history2010-03-29 03:50:44Closed
dimeadozen.orgview history2010-03-29 04:05:06Open
dnbtracker.orgview history2010-03-29 04:01:11Open
docs.torrents.roview history2010-03-29 04:01:14Closed
dvdseed.orgview history2010-03-29 04:32:01Closed
dvdtreasure.euview history2010-03-29 04:05:04Closed
ebookvortex.comview history2010-03-29 04:05:07Open
eclipsetorrents.orgview history2010-03-29 04:12:09Closed
egytorrent.comview history2010-03-29 03:49:06Closed
egytorrent.comview history2010-03-29 04:01:05Closed
elbitz.netview history2010-03-29 04:18:13Closed
elektronik.roview history2010-03-29 03:55:02Closed
empornium.usview history2010-03-29 03:57:07Open
eroticsource.plview history2010-03-29 04:28:19Closed
estrenoslatinos.comview history2010-03-29 03:49:10Closed
ethor.netview history2010-03-29 03:51:08Closed
evopt.orgview history2010-03-29 04:15:06Closed
Exigomusicview history2010-03-29 03:50:45Closed
extremebits.orgview history2010-03-29 04:28:05Closed
extremeshare.orgview history2010-03-29 03:59:03Open
faplife.netview history2010-03-29 03:50:46Closed
feedthe.netview history2010-03-29 04:22:09Closed
filebits.orgview history2010-03-29 03:57:08Closed
filelist.orgview history2010-03-29 04:22:25Closed
filelist.roview history2010-03-29 03:56:09Closed
filemp3.orgview history2010-03-29 03:50:46Closed
fileporn.orgview history2010-03-29 03:51:10Closed
flashtorrents.com.arview history2010-03-29 03:59:40Closed
Free The Scene (FTS)view history2010-03-29 04:05:04Closed
Fresh On TV (TvT)view history2010-03-29 03:59:37Open
frztracker.sytes.netview history2010-03-29 04:25:08Closed
fst.omnilounge.co.ukview history2010-03-29 04:08:50Closed
fullcontactzone.comview history2010-03-29 03:56:09Closed
gamecrook.comview history2010-03-29 04:18:05Closed
gbvnet.roview history2010-03-29 04:25:08Open
gettorrents.orgview history2010-03-29 04:11:06Closed
gfxnews.ruview history2010-03-29 04:12:07Closed
gigatorrents.wsview history2010-03-29 03:57:05Closed
globus-tracker.comview history2010-03-29 04:30:51Closed
goem.orgview history2010-03-29 03:56:07Closed
gormogon.comview history2010-03-29 04:25:05Open
greek-tracker.comview history2010-03-29 03:51:06Closed
grimetorrent.comview history2010-03-29 04:28:15Closed
grtorrent.comview history2010-03-29 04:12:08Closed
guiks.netview history2010-03-29 04:05:04Closed
h264torrents.comview history2010-03-29 03:57:01Closed
h33t.comview history2010-03-29 03:51:06Open
hd-bits.roview history2010-03-29 04:18:09Closed
hd-torrents.orgview history2010-03-29 04:05:05Closed
hdbits.orgview history2010-03-29 04:12:07Closed
hdchina.orgview history2010-03-29 03:59:37Closed
hdfrench.comview history2010-03-29 04:09:01Closed
hdme.euview history2010-03-29 03:55:09Open
hdpre.comview history2010-03-29 04:12:09Closed
hdsource.bizview history2010-03-29 03:49:13Closed
hdstar.orgview history2010-03-29 03:51:02Closed
hdvnbits.orgview history2010-03-29 03:56:03Closed
heaventracker.orgview history2010-03-29 03:57:02Closed
hermeticos.orgview history2010-03-29 04:25:12Closed
horrorcharnel.kicks-ass.orgview history2010-03-29 03:58:05Closed
hungercity.orgview history2010-03-29 04:31:05Open
ifyounotknow.comview history2010-03-29 03:58:07Closed
ilovetorrents.comview history2010-03-29 03:56:06Open
indeep.bizview history2010-03-29 03:56:08Closed
indietorrents.comview history2010-03-29 04:00:14Closed
iplay.roview history2010-03-29 03:59:03Closed
ipodnova.tvview history2010-03-29 04:04:12Closed
iptorrents.comview history2010-03-29 03:51:06Closed
joompalace.comview history2010-03-29 03:57:04Closed
karagarga.netview history2010-03-29 04:17:07Closed
killawaves.netview history2010-03-29 04:05:05Closed
kinozal.wsview history2010-03-29 04:28:16Open
kludd.comview history2010-03-29 03:55:11Closed
lasttorrents.orgview history2010-03-29 04:32:02Open
leecherslair.comview history2010-03-29 04:18:08Closed
libble.comview history2010-03-29 04:25:11Closed
libitina.netview history2010-03-29 04:18:11Closed
linuxmafia.netview history2010-03-29 04:22:07Offline
linuxtracker.orgview history2010-03-29 04:22:24Closed
lostfilm.tvview history2010-03-29 04:00:07Open
magiciantorrents.comview history2010-03-29 03:55:14Closed
masterstb.comview history2010-03-29 03:56:12Closed
mazetorrents.netview history2010-03-29 04:17:07Offline
medioteka.comview history2010-03-29 04:17:07Closed
mega-bits.comview history2010-03-29 03:51:52Closed
mentol.roview history2010-03-29 04:12:04Closed
metal.iplay.roview history2010-03-29 04:18:03Closed
metalbits.orgview history2010-03-29 04:00:02Closed
midnight-scene.comview history2010-03-29 03:58:06Closed
midnight-torrents.comview history2010-03-29 04:31:05Closed
mma-central.org.ukview history2010-03-29 03:56:05Closed
mma-tracker.netview history2010-03-29 03:50:43Closed
mp3nerds.orgview history2010-03-29 04:18:07Closed
mucis-vid.comview history2010-03-29 03:56:06Closed
musicplace.lvview history2010-03-29 04:05:04Closed
mytorrent.tvview history2010-03-29 03:57:07Closed
norbits.netview history2010-03-29 04:12:05Closed
nordic-t.orgview history2010-03-29 03:55:02Closed
nordicbits.orgview history2010-03-29 04:18:07Offline
novaro.infoview history2010-03-29 03:49:16Closed
novaro.infoview history2010-03-29 03:55:02Closed
noviteti.comview history2010-03-29 04:15:05Offline
ntorrents.netview history2010-03-29 03:59:08Closed
nutorrent.comview history2010-03-29 04:25:12Open
opennetwork.roview history2010-03-29 04:08:49Closed
overtopropetorrents.comview history2010-03-29 04:00:14Closed
ozone-torrents.orgview history2010-03-29 04:32:00Closed
Pedros btmusicview history2010-03-29 04:08:54Closed
pianosheets.orgview history2010-03-29 03:49:17Closed
pinkytorrents.comview history2010-03-29 03:56:08Open
piranha.excom.usview history2010-03-29 04:08:07Open
Pirate The Net (PtN)view history2010-03-29 03:49:15Closed
piratebits.orgview history2010-03-29 04:09:01Closed
piratefiles.seview history2010-03-29 04:25:05Closed
piratetorrents.nuview history2010-03-29 03:56:04Closed
pisexy.orgview history2010-03-29 04:01:06Closed
polishbytes.netview history2010-03-29 04:31:55Open
polishtracker.orgview history2010-03-29 03:56:09Closed
pornbay.orgview history2010-03-29 03:57:12Closed
PotUKview history2010-03-29 04:08:54Closed
powerscene.orgview history2010-03-29 03:57:11Closed
pretome.netview history2010-03-29 04:32:01Closed
proaudiotorrents.orgview history2010-03-29 04:15:14Closed
psytorrents.infoview history2010-03-29 03:49:08Closed
ptfiles.orgview history2010-03-29 04:18:09Closed
punkhc.dyndns.orgview history2010-03-29 04:01:09Closed
puretna.comview history2010-03-29 04:05:06Open
pussytorrents.orgview history2010-03-29 03:52:02Open
rapthe.netview history2010-03-29 04:12:09Closed
rarbg.comview history2010-03-29 03:58:11Open
reload-paradise.netview history2010-03-29 04:00:07Closed
revolutiontt.netview history2010-03-29 03:56:07Closed
rmvbustersview history2010-03-29 04:15:08Open
rmvbusters.plview history2010-03-29 03:56:05Open
scaliwags.orgview history2010-03-29 03:59:04Closed
scene-gold.infoview history2010-03-29 04:17:08Offline
scene-inspired.comview history2010-03-29 03:51:07Open
sceneaccess.orgview history2010-03-29 03:55:09Closed
scenebytes.clview history2010-03-29 04:22:20Closed
scenehd.orgview history2010-03-29 04:28:09Closed
sceneleech.orgview history2010-03-29 03:57:05Closed
SceneLife (ScL)view history2010-03-29 04:00:08Closed
scenetorrents.orgview history2010-03-29 04:12:05Closed
scenetuga.orgview history2010-03-29 03:51:04Closed
sciencehd.netview history2010-03-29 04:00:15Closed
scifitorrents.netview history2010-03-29 03:56:10Closed
secret-cinema.netview history2010-03-29 04:28:13Closed
seedgames.orgview history2010-03-29 04:18:16Closed
seedmore.orgview history2010-03-29 03:56:11Closed
sharetorrents.plview history2010-03-29 04:01:13Closed
sharing-torrents.comview history2010-03-29 03:58:14Closed
slosoul.netview history2010-03-29 03:51:00Closed
snowtigers.netview history2010-03-29 03:49:43Closed
softmp3.orgview history2010-03-29 04:18:02Closed
softmupparna.netview history2010-03-29 04:31:05Closed
sounddamage.comview history2010-03-29 03:49:14Closed
spanishtracker.comview history2010-03-29 04:25:07Open
spank-d-monkey.comview history2010-03-29 04:17:09Closed
special.pwtorrents.netview history2010-03-29 03:56:06Closed
speed.cdview history2010-03-29 03:52:02Closed
spiryt.ath.cxview history2010-03-29 04:12:07Closed
sport-scene.netview history2010-03-29 03:55:15Closed
sportbit.orgview history2010-03-29 04:25:08Closed
sportleech.netview history2010-03-29 04:28:08Closed
stmusic.orgview history2010-03-29 04:05:04Open
supertorrents.orgview history2010-03-29 04:05:08Open
swebits.orgview history2010-03-29 04:15:05Closed
sweninjaz.orgview history2010-03-29 04:32:02Closed
swep2p.orgview history2010-03-29 03:51:52Closed
swepiracy.orgview history2010-03-29 04:05:07Open
swetorrents.no-ip.orgview history2010-03-29 04:31:05Closed
taiphimhd.comview history2010-03-29 03:55:07Closed
tastetherainbow.wsview history2010-03-29 04:00:04Closed
teamofgreekz.comview history2010-03-29 04:18:03Closed
tehconnection.euview history2010-03-29 04:28:06Closed
the-zomb.comview history2010-03-29 04:08:55Open
thebox.bzview history2010-03-29 03:51:06Open
thedvdclub.orgview history2010-03-29 04:25:07Open
thegt.netview history2010-03-29 04:31:58Closed
themixingbowl.orgview history2010-03-29 04:22:25Closed
theoccult.bzview history2010-03-29 03:51:02Closed
thepeerhub.comview history2010-03-29 04:00:12Open
theplace.bzview history2010-03-29 04:08:56Closed
thepokerbay.orgview history2010-03-29 03:59:37Open
thevault.bzview history2010-03-29 03:59:39Closed
titaniumtorrents.netview history2010-03-29 04:18:11Offline
tmtorrents.orgview history2010-03-29 03:49:12Closed
topbytes.netview history2010-03-29 03:49:08Closed
topbytes.netview history2010-03-29 04:05:05Closed
tophos.orgview history2010-03-29 03:58:09Closed
torrent-damage.netview history2010-03-29 03:50:45Closed
torrent.itview history2010-03-29 04:25:12Closed
torrent411.comview history2010-03-29 04:15:08Open
torrentbits.roview history2010-03-29 04:31:57Closed
torrentbully.comview history2010-03-29 03:55:08Closed
torrentdownloads.netview history2010-03-29 04:15:05Open
torrentgaming.netview history2010-03-29 04:28:18Closed
torrentgeeks.comview history2010-03-29 03:51:02Offline
torrenthr.orgview history2010-03-29 04:21:10Open
torrentkings.orgview history2010-03-29 03:49:05Closed
torrentleech.orgview history2010-03-29 04:01:09Closed
torrentseed.orgview history2010-03-29 03:56:10Closed
torrentsforall.netview history2010-03-29 04:15:07Open
torrentsmd.comview history2010-03-29 04:00:09Closed
torrentvault.orgview history2010-03-29 03:49:12Closed
torrentzilla.orgview history2010-03-29 03:57:04Open
torrentzone.netview history2010-03-29 04:18:03Open
totaltorrents.comview history2010-03-29 04:05:05Closed
trancebits.comview history2010-03-29 04:25:09Closed
trancebooster.netview history2010-03-29 04:05:03Closed
trancetraffic.comview history2010-03-29 04:12:10Closed
tri-tavern.comview history2010-03-29 04:17:07Closed
tribalmixes.comview history2010-03-29 04:15:07Open
tugaleech.comview history2010-03-29 03:59:05Closed
tunebully.comview history2010-03-29 04:25:09Closed
tv.torrents.roview history2010-03-29 03:58:06Closed
tvtorrents.comview history2010-03-29 04:18:05Open
ugstorrents.comview history2010-03-29 04:28:11Closed
uknova.comview history2010-03-29 04:22:26Closed
underground-gamer.comview history2010-03-29 04:17:07Open
victorrent.netview history2010-03-29 04:01:09Closed
vortexnetwork.orgview history2010-03-29 03:56:08Offline
waffles.fmview history2010-03-29 03:56:11Closed
wantedfiles.roview history2010-03-29 04:18:06Open
warezbros.orgview history2010-03-29 04:08:59Closed
what.cdview history2010-03-29 04:22:27Closed
wild-bytes.orgview history2010-03-29 04:12:07Closed
wolfbits.orgview history2010-03-29 04:22:07Closed
worldboxingvideoarchive.comview history2010-03-29 04:05:06Open
www.bt-pt.netview history2010-03-29 03:56:05Open
www.llywot.comview history2010-03-29 03:59:38Closed
xbitz.orgview history2010-03-29 04:18:14Open
xider.huview history2010-03-29 04:05:02Open
xtremespeeds.netview history2010-03-29 04:01:04Closed
xtremewrestlingtorrents.netview history2010-03-29 03:51:05Closed
xtremezone.roview history2010-03-29 03:58:08Closed
yuwabits.netview history2010-03-29 04:05:07Open
zanettetorrent.comview history2010-03-29 04:00:10Open
zinebytes.orgview history2010-03-29 04:25:10Closed
+
+


+ + + +
+ + + + + + diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.51378~ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.51378~ new file mode 100644 index 0000000..e000284 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.51378~ @@ -0,0 +1,2948 @@ + + + +www.trackerchecker.com - We check your trackers + + + + + + +
+ + + + + + + +
Home || Add a tracker || Latest trackers
+
+ + +
+follow us on Twitter
+Follow trackerchecker on Twitter --> @trackerchecker. +
+ +
+ + +
+
+ TrackerList
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 TrackerNameHistoryLastCheckedStatus
1337x.orgview history2010-03-29 03:56:03Open
420project.orgview history2010-03-29 04:28:13Closed
acehd.netview history2010-03-29 04:31:58Closed
acetorrents.netview history2010-03-29 03:59:08Open
adult-cinema-network.netview history2010-03-29 04:00:08Open
all4nothin.netview history2010-03-29 04:01:08Open
allgirltorrents.comview history2010-03-29 03:50:57Closed
allotracker.comview history2010-03-29 03:58:09Open
appz.bitshock.orgview history2010-03-29 03:57:12Open
appzuniverse.orgview history2010-03-29 04:18:04Closed
arabfilms.orgview history2010-03-29 04:08:50Closed
arabseries.orgview history2010-03-29 03:59:39Closed
araditracker.comview history2010-03-29 04:22:25Closed
arena-tr.comview history2010-03-29 04:12:10Closed
arenabg.comview history2010-03-29 03:51:00Closed
artofmisdirection.comview history2010-03-29 04:01:04Closed
asiandvdclub.orgview history2010-03-29 04:18:15Open
at-tracker.orgview history2010-03-29 04:15:08Offline
atomico-torrent.comview history2010-03-29 03:56:05Closed
audionews.ruview history2010-03-29 04:01:02Closed
audiotracer.comview history2010-03-29 04:05:08Closed
audiozonetorrents.comview history2010-03-29 03:56:09Open
avatarbg.infoview history2010-03-29 03:49:14Closed
awesome-hd.comview history2010-03-29 03:51:07Closed
awesome-hd.netview history2010-03-29 03:55:09Closed
baltracker.netview history2010-03-29 04:15:09Open
bestmmatorrents.comview history2010-03-29 04:15:04Closed
bestshare.roview history2010-03-29 03:56:11Closed
bestxvid.orgview history2010-03-29 03:50:57Closed
bit-hdtv.comview history2010-03-29 03:58:10Closed
bitaddict.orgview history2010-03-29 03:50:45Closed
bitchil.comview history2010-03-29 03:56:09Open
bitflamers.comview history2010-03-29 04:01:12Closed
bitgamer.comview history2010-03-29 04:12:08Closed
bithq.orgview history2010-03-29 03:58:08Open
bithumen.ath.cxview history2010-03-29 04:22:20Closed
bitlove.huview history2010-03-29 04:25:10Closed
bitme.orgview history2010-03-29 04:12:06Closed
bitmetv.orgview history2010-03-29 03:49:16Closed
bitmusic.huview history2010-03-29 03:58:11Closed
bitnation.comview history2010-03-29 03:59:08Closed
bitseduce.comview history2010-03-29 04:05:08Closed
bitseek.orgview history2010-03-29 04:28:05Closed
bitseek.orgview history2010-03-29 04:18:05Closed
bitshock.orgview history2010-03-29 04:00:03Open
bitshock.orgview history2010-03-29 03:55:14Closed
bitsoup.orgview history2010-03-29 03:59:07Open
bitSpyder.netview history2010-03-29 03:56:06Closed
bittorrents.roview history2010-03-29 04:00:14Closed
bitturk.netview history2010-03-29 03:56:05Closed
biztorrents.comview history2010-03-29 04:15:07Open
blackcats-games.netview history2010-03-29 03:58:06Closed
blades-heaven.comview history2010-03-29 04:08:56Open
blue-bytez.comview history2010-03-29 04:32:01Closed
blue-whitegt.comview history2010-03-29 04:28:13Closed
bmtorrents.netview history2010-03-29 03:58:10Closed
bootytape.comview history2010-03-29 03:58:02Open
bootytorrents.comview history2010-03-29 03:57:07Closed
boxtorrents.comview history2010-03-29 04:08:59Closed
bt.avistaz.comview history2010-03-29 04:15:08Closed
bt.davka.infoview history2010-03-29 04:08:50Open
bt.xbox-sky.ccview history2010-03-29 03:49:08Closed
bt.xbox-sky.comview history2010-03-29 03:50:42Closed
btgigs.infoview history2010-03-29 04:18:15Closed
bwtorrents.comview history2010-03-29 03:56:10Closed
bytelist.orgview history2010-03-29 04:05:07Offline
cartoonchaos.orgview history2010-03-29 04:18:15Closed
ccfbits.orgview history2010-03-29 04:22:19Closed
chdbits.orgview history2010-03-29 04:15:11Closed
cheggit.net/view history2010-03-29 04:09:00Open
chilebt.comview history2010-03-29 04:22:11Closed
christiantorrents.comview history2010-03-29 04:28:13Closed
chronictracker.comview history2010-03-29 04:01:13Closed
cinema-obscura.comview history2010-03-29 03:57:06Closed
cinemageddon.orgview history2010-03-29 04:22:27Closed
cinematik.netview history2010-03-29 03:57:11Closed
cleanvobs.orgview history2010-03-29 03:49:43Closed
colombo-bt.orgview history2010-03-29 03:50:55Closed
contego.wsview history2010-03-29 04:22:12Closed
crazytorrent.euview history2010-03-29 04:08:49Closed
czone.roview history2010-03-29 04:24:09Closed
danger.lvview history2010-03-29 03:55:15Closed
demonoid.comview history2010-03-29 04:18:15Closed
devilwolfs.comview history2010-03-29 04:31:55Closed
diablotorrent.huview history2010-03-29 03:56:01Closed
dididave.comview history2010-03-29 04:00:03Closed
digitalhive.orgview history2010-03-29 03:50:44Closed
dimeadozen.orgview history2010-03-29 04:05:06Open
dnbtracker.orgview history2010-03-29 04:01:11Open
docs.torrents.roview history2010-03-29 04:01:14Closed
dvdseed.orgview history2010-03-29 04:32:01Closed
dvdtreasure.euview history2010-03-29 04:05:04Closed
ebookvortex.comview history2010-03-29 04:05:07Open
eclipsetorrents.orgview history2010-03-29 04:12:09Closed
egytorrent.comview history2010-03-29 03:49:06Closed
egytorrent.comview history2010-03-29 04:01:05Closed
elbitz.netview history2010-03-29 04:18:13Closed
elektronik.roview history2010-03-29 03:55:02Closed
empornium.usview history2010-03-29 03:57:07Open
eroticsource.plview history2010-03-29 04:28:19Closed
estrenoslatinos.comview history2010-03-29 03:49:10Closed
ethor.netview history2010-03-29 03:51:08Closed
evopt.orgview history2010-03-29 04:15:06Closed
Exigomusicview history2010-03-29 03:50:45Closed
extremebits.orgview history2010-03-29 04:28:05Closed
extremeshare.orgview history2010-03-29 03:59:03Open
faplife.netview history2010-03-29 03:50:46Closed
feedthe.netview history2010-03-29 04:22:09Closed
filebits.orgview history2010-03-29 03:57:08Closed
filelist.orgview history2010-03-29 04:22:25Closed
filelist.roview history2010-03-29 03:56:09Closed
filemp3.orgview history2010-03-29 03:50:46Closed
fileporn.orgview history2010-03-29 03:51:10Closed
flashtorrents.com.arview history2010-03-29 03:59:40Closed
Free The Scene (FTS)view history2010-03-29 04:05:04Closed
Fresh On TV (TvT)view history2010-03-29 03:59:37Open
frztracker.sytes.netview history2010-03-29 04:25:08Closed
fst.omnilounge.co.ukview history2010-03-29 04:08:50Closed
fullcontactzone.comview history2010-03-29 03:56:09Closed
gamecrook.comview history2010-03-29 04:18:05Closed
gbvnet.roview history2010-03-29 04:25:08Open
gettorrents.orgview history2010-03-29 04:11:06Closed
gfxnews.ruview history2010-03-29 04:12:07Closed
gigatorrents.wsview history2010-03-29 03:57:05Closed
globus-tracker.comview history2010-03-29 04:30:51Closed
goem.orgview history2010-03-29 03:56:07Closed
gormogon.comview history2010-03-29 04:25:05Open
greek-tracker.comview history2010-03-29 03:51:06Closed
grimetorrent.comview history2010-03-29 04:28:15Closed
grtorrent.comview history2010-03-29 04:12:08Closed
guiks.netview history2010-03-29 04:05:04Closed
h264torrents.comview history2010-03-29 03:57:01Closed
h33t.comview history2010-03-29 03:51:06Open
hd-bits.roview history2010-03-29 04:18:09Closed
hd-torrents.orgview history2010-03-29 04:05:05Closed
hdbits.orgview history2010-03-29 04:12:07Closed
hdchina.orgview history2010-03-29 03:59:37Closed
hdfrench.comview history2010-03-29 04:09:01Closed
hdme.euview history2010-03-29 03:55:09Open
hdpre.comview history2010-03-29 04:12:09Closed
hdsource.bizview history2010-03-29 03:49:13Closed
hdstar.orgview history2010-03-29 03:51:02Closed
hdvnbits.orgview history2010-03-29 03:56:03Closed
heaventracker.orgview history2010-03-29 03:57:02Closed
hermeticos.orgview history2010-03-29 04:25:12Closed
horrorcharnel.kicks-ass.orgview history2010-03-29 03:58:05Closed
hungercity.orgview history2010-03-29 04:31:05Open
ifyounotknow.comview history2010-03-29 03:58:07Closed
ilovetorrents.comview history2010-03-29 03:56:06Open
indeep.bizview history2010-03-29 03:56:08Closed
indietorrents.comview history2010-03-29 04:00:14Closed
iplay.roview history2010-03-29 03:59:03Closed
ipodnova.tvview history2010-03-29 04:04:12Closed
iptorrents.comview history2010-03-29 03:51:06Closed
joompalace.comview history2010-03-29 03:57:04Closed
karagarga.netview history2010-03-29 04:17:07Closed
killawaves.netview history2010-03-29 04:05:05Closed
kinozal.wsview history2010-03-29 04:28:16Open
kludd.comview history2010-03-29 03:55:11Closed
lasttorrents.orgview history2010-03-29 04:32:02Open
leecherslair.comview history2010-03-29 04:18:08Closed
libble.comview history2010-03-29 04:25:11Closed
libitina.netview history2010-03-29 04:18:11Closed
linuxmafia.netview history2010-03-29 04:22:07Offline
linuxtracker.orgview history2010-03-29 04:22:24Closed
lostfilm.tvview history2010-03-29 04:00:07Open
magiciantorrents.comview history2010-03-29 03:55:14Closed
masterstb.comview history2010-03-29 03:56:12Closed
mazetorrents.netview history2010-03-29 04:17:07Offline
medioteka.comview history2010-03-29 04:17:07Closed
mega-bits.comview history2010-03-29 03:51:52Closed
mentol.roview history2010-03-29 04:12:04Closed
metal.iplay.roview history2010-03-29 04:18:03Closed
metalbits.orgview history2010-03-29 04:00:02Closed
midnight-scene.comview history2010-03-29 03:58:06Closed
midnight-torrents.comview history2010-03-29 04:31:05Closed
mma-central.org.ukview history2010-03-29 03:56:05Closed
mma-tracker.netview history2010-03-29 03:50:43Closed
mp3nerds.orgview history2010-03-29 04:18:07Closed
mucis-vid.comview history2010-03-29 03:56:06Closed
musicplace.lvview history2010-03-29 04:05:04Closed
mytorrent.tvview history2010-03-29 03:57:07Closed
norbits.netview history2010-03-29 04:12:05Closed
nordic-t.orgview history2010-03-29 03:55:02Closed
nordicbits.orgview history2010-03-29 04:18:07Offline
novaro.infoview history2010-03-29 03:49:16Closed
novaro.infoview history2010-03-29 03:55:02Closed
noviteti.comview history2010-03-29 04:15:05Offline
ntorrents.netview history2010-03-29 03:59:08Closed
nutorrent.comview history2010-03-29 04:25:12Open
opennetwork.roview history2010-03-29 04:08:49Closed
overtopropetorrents.comview history2010-03-29 04:00:14Closed
ozone-torrents.orgview history2010-03-29 04:32:00Closed
Pedros btmusicview history2010-03-29 04:08:54Closed
pianosheets.orgview history2010-03-29 03:49:17Closed
pinkytorrents.comview history2010-03-29 03:56:08Open
piranha.excom.usview history2010-03-29 04:08:07Open
Pirate The Net (PtN)view history2010-03-29 03:49:15Closed
piratebits.orgview history2010-03-29 04:09:01Closed
piratefiles.seview history2010-03-29 04:25:05Closed
piratetorrents.nuview history2010-03-29 03:56:04Closed
pisexy.orgview history2010-03-29 04:01:06Closed
polishbytes.netview history2010-03-29 04:31:55Open
polishtracker.orgview history2010-03-29 03:56:09Closed
pornbay.orgview history2010-03-29 03:57:12Closed
PotUKview history2010-03-29 04:08:54Closed
powerscene.orgview history2010-03-29 03:57:11Closed
pretome.netview history2010-03-29 04:32:01Closed
proaudiotorrents.orgview history2010-03-29 04:15:14Closed
psytorrents.infoview history2010-03-29 03:49:08Closed
ptfiles.orgview history2010-03-29 04:18:09Closed
punkhc.dyndns.orgview history2010-03-29 04:01:09Closed
puretna.comview history2010-03-29 04:05:06Open
pussytorrents.orgview history2010-03-29 03:52:02Open
rapthe.netview history2010-03-29 04:12:09Closed
rarbg.comview history2010-03-29 03:58:11Open
reload-paradise.netview history2010-03-29 04:00:07Closed
revolutiontt.netview history2010-03-29 03:56:07Closed
rmvbustersview history2010-03-29 04:15:08Open
rmvbusters.plview history2010-03-29 03:56:05Open
scaliwags.orgview history2010-03-29 03:59:04Closed
scene-gold.infoview history2010-03-29 04:17:08Offline
scene-inspired.comview history2010-03-29 03:51:07Open
sceneaccess.orgview history2010-03-29 03:55:09Closed
scenebytes.clview history2010-03-29 04:22:20Closed
scenehd.orgview history2010-03-29 04:28:09Closed
sceneleech.orgview history2010-03-29 03:57:05Closed
SceneLife (ScL)view history2010-03-29 04:00:08Closed
scenetorrents.orgview history2010-03-29 04:12:05Closed
scenetuga.orgview history2010-03-29 03:51:04Closed
sciencehd.netview history2010-03-29 04:00:15Closed
scifitorrents.netview history2010-03-29 03:56:10Closed
secret-cinema.netview history2010-03-29 04:28:13Closed
seedgames.orgview history2010-03-29 04:18:16Closed
seedmore.orgview history2010-03-29 03:56:11Closed
sharetorrents.plview history2010-03-29 04:01:13Closed
sharing-torrents.comview history2010-03-29 03:58:14Closed
slosoul.netview history2010-03-29 03:51:00Closed
snowtigers.netview history2010-03-29 03:49:43Closed
softmp3.orgview history2010-03-29 04:18:02Closed
softmupparna.netview history2010-03-29 04:31:05Closed
sounddamage.comview history2010-03-29 03:49:14Closed
spanishtracker.comview history2010-03-29 04:25:07Open
spank-d-monkey.comview history2010-03-29 04:17:09Closed
special.pwtorrents.netview history2010-03-29 03:56:06Closed
speed.cdview history2010-03-29 03:52:02Closed
spiryt.ath.cxview history2010-03-29 04:12:07Closed
sport-scene.netview history2010-03-29 03:55:15Closed
sportbit.orgview history2010-03-29 04:25:08Closed
sportleech.netview history2010-03-29 04:28:08Closed
stmusic.orgview history2010-03-29 04:05:04Open
supertorrents.orgview history2010-03-29 04:05:08Open
swebits.orgview history2010-03-29 04:15:05Closed
sweninjaz.orgview history2010-03-29 04:32:02Closed
swep2p.orgview history2010-03-29 03:51:52Closed
swepiracy.orgview history2010-03-29 04:05:07Open
swetorrents.no-ip.orgview history2010-03-29 04:31:05Closed
taiphimhd.comview history2010-03-29 03:55:07Closed
tastetherainbow.wsview history2010-03-29 04:00:04Closed
teamofgreekz.comview history2010-03-29 04:18:03Closed
tehconnection.euview history2010-03-29 04:28:06Closed
the-zomb.comview history2010-03-29 04:08:55Open
thebox.bzview history2010-03-29 03:51:06Open
thedvdclub.orgview history2010-03-29 04:25:07Open
thegt.netview history2010-03-29 04:31:58Closed
themixingbowl.orgview history2010-03-29 04:22:25Closed
theoccult.bzview history2010-03-29 03:51:02Closed
thepeerhub.comview history2010-03-29 04:00:12Open
theplace.bzview history2010-03-29 04:08:56Closed
thepokerbay.orgview history2010-03-29 03:59:37Open
thevault.bzview history2010-03-29 03:59:39Closed
titaniumtorrents.netview history2010-03-29 04:18:11Offline
tmtorrents.orgview history2010-03-29 03:49:12Closed
topbytes.netview history2010-03-29 03:49:08Closed
topbytes.netview history2010-03-29 04:05:05Closed
tophos.orgview history2010-03-29 03:58:09Closed
torrent-damage.netview history2010-03-29 03:50:45Closed
torrent.itview history2010-03-29 04:25:12Closed
torrent411.comview history2010-03-29 04:15:08Open
torrentbits.roview history2010-03-29 04:31:57Closed
torrentbully.comview history2010-03-29 03:55:08Closed
torrentdownloads.netview history2010-03-29 04:15:05Open
torrentgaming.netview history2010-03-29 04:28:18Closed
torrentgeeks.comview history2010-03-29 03:51:02Offline
torrenthr.orgview history2010-03-29 04:21:10Open
torrentkings.orgview history2010-03-29 03:49:05Closed
torrentleech.orgview history2010-03-29 04:01:09Closed
torrentseed.orgview history2010-03-29 03:56:10Closed
torrentsforall.netview history2010-03-29 04:15:07Open
torrentsmd.comview history2010-03-29 04:00:09Closed
torrentvault.orgview history2010-03-29 03:49:12Closed
torrentzilla.orgview history2010-03-29 03:57:04Open
torrentzone.netview history2010-03-29 04:18:03Open
totaltorrents.comview history2010-03-29 04:05:05Closed
trancebits.comview history2010-03-29 04:25:09Closed
trancebooster.netview history2010-03-29 04:05:03Closed
trancetraffic.comview history2010-03-29 04:12:10Closed
tri-tavern.comview history2010-03-29 04:17:07Closed
tribalmixes.comview history2010-03-29 04:15:07Open
tugaleech.comview history2010-03-29 03:59:05Closed
tunebully.comview history2010-03-29 04:25:09Closed
tv.torrents.roview history2010-03-29 03:58:06Closed
tvtorrents.comview history2010-03-29 04:18:05Open
ugstorrents.comview history2010-03-29 04:28:11Closed
uknova.comview history2010-03-29 04:22:26Closed
underground-gamer.comview history2010-03-29 04:17:07Open
victorrent.netview history2010-03-29 04:01:09Closed
vortexnetwork.orgview history2010-03-29 03:56:08Offline
waffles.fmview history2010-03-29 03:56:11Closed
wantedfiles.roview history2010-03-29 04:18:06Open
warezbros.orgview history2010-03-29 04:08:59Closed
what.cdview history2010-03-29 04:22:27Closed
wild-bytes.orgview history2010-03-29 04:12:07Closed
wolfbits.orgview history2010-03-29 04:22:07Closed
worldboxingvideoarchive.comview history2010-03-29 04:05:06Open
www.bt-pt.netview history2010-03-29 03:56:05Open
www.llywot.comview history2010-03-29 03:59:38Closed
xbitz.orgview history2010-03-29 04:18:14Open
xider.huview history2010-03-29 04:05:02Open
xtremespeeds.netview history2010-03-29 04:01:04Closed
xtremewrestlingtorrents.netview history2010-03-29 03:51:05Closed
xtremezone.roview history2010-03-29 03:58:08Closed
yuwabits.netview history2010-03-29 04:05:07Open
zanettetorrent.comview history2010-03-29 04:00:10Open
zinebytes.orgview history2010-03-29 04:25:10Closed
+
+


+ + + +
+ + + + + + diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.75287~ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.75287~ new file mode 100644 index 0000000..1eea80d --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/.tmp_trackerchecker2.html.75287~ @@ -0,0 +1,2947 @@ + + +www.trackerchecker.com - We check your trackers + + + + + + +
+ + + + + + + +
Home || Add a tracker || Latest trackers
+
+ + +
+follow us on Twitter
+Follow trackerchecker on Twitter --> @trackerchecker. +
+ +
+ + +
+
+ TrackerList
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 TrackerNameHistoryLastCheckedStatus
1337x.orgview history2010-03-29 03:56:03Open
420project.orgview history2010-03-29 04:28:13Closed
acehd.netview history2010-03-29 04:31:58Closed
acetorrents.netview history2010-03-29 03:59:08Open
adult-cinema-network.netview history2010-03-29 04:00:08Open
all4nothin.netview history2010-03-29 04:01:08Open
allgirltorrents.comview history2010-03-29 03:50:57Closed
allotracker.comview history2010-03-29 03:58:09Open
appz.bitshock.orgview history2010-03-29 03:57:12Open
appzuniverse.orgview history2010-03-29 04:18:04Closed
arabfilms.orgview history2010-03-29 04:08:50Closed
arabseries.orgview history2010-03-29 03:59:39Closed
araditracker.comview history2010-03-29 04:22:25Closed
arena-tr.comview history2010-03-29 04:12:10Closed
arenabg.comview history2010-03-29 03:51:00Closed
artofmisdirection.comview history2010-03-29 04:01:04Closed
asiandvdclub.orgview history2010-03-29 04:18:15Open
at-tracker.orgview history2010-03-29 04:15:08Offline
atomico-torrent.comview history2010-03-29 03:56:05Closed
audionews.ruview history2010-03-29 04:01:02Closed
audiotracer.comview history2010-03-29 04:05:08Closed
audiozonetorrents.comview history2010-03-29 03:56:09Open
avatarbg.infoview history2010-03-29 03:49:14Closed
awesome-hd.comview history2010-03-29 03:51:07Closed
awesome-hd.netview history2010-03-29 03:55:09Closed
baltracker.netview history2010-03-29 04:15:09Open
bestmmatorrents.comview history2010-03-29 04:15:04Closed
bestshare.roview history2010-03-29 03:56:11Closed
bestxvid.orgview history2010-03-29 03:50:57Closed
bit-hdtv.comview history2010-03-29 03:58:10Closed
bitaddict.orgview history2010-03-29 03:50:45Closed
bitchil.comview history2010-03-29 03:56:09Open
bitflamers.comview history2010-03-29 04:01:12Closed
bitgamer.comview history2010-03-29 04:12:08Closed
bithq.orgview history2010-03-29 03:58:08Open
bithumen.ath.cxview history2010-03-29 04:22:20Closed
bitlove.huview history2010-03-29 04:25:10Closed
bitme.orgview history2010-03-29 04:12:06Closed
bitmetv.orgview history2010-03-29 03:49:16Closed
bitmusic.huview history2010-03-29 03:58:11Closed
bitnation.comview history2010-03-29 03:59:08Closed
bitseduce.comview history2010-03-29 04:05:08Closed
bitseek.orgview history2010-03-29 04:28:05Closed
bitseek.orgview history2010-03-29 04:18:05Closed
bitshock.orgview history2010-03-29 04:00:03Open
bitshock.orgview history2010-03-29 03:55:14Closed
bitsoup.orgview history2010-03-29 03:59:07Open
bitSpyder.netview history2010-03-29 03:56:06Closed
bittorrents.roview history2010-03-29 04:00:14Closed
bitturk.netview history2010-03-29 03:56:05Closed
biztorrents.comview history2010-03-29 04:15:07Open
blackcats-games.netview history2010-03-29 03:58:06Closed
blades-heaven.comview history2010-03-29 04:08:56Open
blue-bytez.comview history2010-03-29 04:32:01Closed
blue-whitegt.comview history2010-03-29 04:28:13Closed
bmtorrents.netview history2010-03-29 03:58:10Closed
bootytape.comview history2010-03-29 03:58:02Open
bootytorrents.comview history2010-03-29 03:57:07Closed
boxtorrents.comview history2010-03-29 04:08:59Closed
bt.avistaz.comview history2010-03-29 04:15:08Closed
bt.davka.infoview history2010-03-29 04:08:50Open
bt.xbox-sky.ccview history2010-03-29 03:49:08Closed
bt.xbox-sky.comview history2010-03-29 03:50:42Closed
btgigs.infoview history2010-03-29 04:18:15Closed
bwtorrents.comview history2010-03-29 03:56:10Closed
bytelist.orgview history2010-03-29 04:05:07Offline
cartoonchaos.orgview history2010-03-29 04:18:15Closed
ccfbits.orgview history2010-03-29 04:22:19Closed
chdbits.orgview history2010-03-29 04:15:11Closed
cheggit.net/view history2010-03-29 04:09:00Open
chilebt.comview history2010-03-29 04:22:11Closed
christiantorrents.comview history2010-03-29 04:28:13Closed
chronictracker.comview history2010-03-29 04:01:13Closed
cinema-obscura.comview history2010-03-29 03:57:06Closed
cinemageddon.orgview history2010-03-29 04:22:27Closed
cinematik.netview history2010-03-29 03:57:11Closed
cleanvobs.orgview history2010-03-29 03:49:43Closed
colombo-bt.orgview history2010-03-29 03:50:55Closed
contego.wsview history2010-03-29 04:22:12Closed
crazytorrent.euview history2010-03-29 04:08:49Closed
czone.roview history2010-03-29 04:24:09Closed
danger.lvview history2010-03-29 03:55:15Closed
demonoid.comview history2010-03-29 04:18:15Closed
devilwolfs.comview history2010-03-29 04:31:55Closed
diablotorrent.huview history2010-03-29 03:56:01Closed
dididave.comview history2010-03-29 04:00:03Closed
digitalhive.orgview history2010-03-29 03:50:44Closed
dimeadozen.orgview history2010-03-29 04:05:06Open
dnbtracker.orgview history2010-03-29 04:01:11Open
docs.torrents.roview history2010-03-29 04:01:14Closed
dvdseed.orgview history2010-03-29 04:32:01Closed
dvdtreasure.euview history2010-03-29 04:05:04Closed
ebookvortex.comview history2010-03-29 04:05:07Open
eclipsetorrents.orgview history2010-03-29 04:12:09Closed
egytorrent.comview history2010-03-29 03:49:06Closed
egytorrent.comview history2010-03-29 04:01:05Closed
elbitz.netview history2010-03-29 04:18:13Closed
elektronik.roview history2010-03-29 03:55:02Closed
empornium.usview history2010-03-29 03:57:07Open
eroticsource.plview history2010-03-29 04:28:19Closed
estrenoslatinos.comview history2010-03-29 03:49:10Closed
ethor.netview history2010-03-29 03:51:08Closed
evopt.orgview history2010-03-29 04:15:06Closed
Exigomusicview history2010-03-29 03:50:45Closed
extremebits.orgview history2010-03-29 04:28:05Closed
extremeshare.orgview history2010-03-29 03:59:03Open
faplife.netview history2010-03-29 03:50:46Closed
feedthe.netview history2010-03-29 04:22:09Closed
filebits.orgview history2010-03-29 03:57:08Closed
filelist.orgview history2010-03-29 04:22:25Closed
filelist.roview history2010-03-29 03:56:09Closed
filemp3.orgview history2010-03-29 03:50:46Closed
fileporn.orgview history2010-03-29 03:51:10Closed
flashtorrents.com.arview history2010-03-29 03:59:40Closed
Free The Scene (FTS)view history2010-03-29 04:05:04Closed
Fresh On TV (TvT)view history2010-03-29 03:59:37Open
frztracker.sytes.netview history2010-03-29 04:25:08Closed
fst.omnilounge.co.ukview history2010-03-29 04:08:50Closed
fullcontactzone.comview history2010-03-29 03:56:09Closed
gamecrook.comview history2010-03-29 04:18:05Closed
gbvnet.roview history2010-03-29 04:25:08Open
gettorrents.orgview history2010-03-29 04:11:06Closed
gfxnews.ruview history2010-03-29 04:12:07Closed
gigatorrents.wsview history2010-03-29 03:57:05Closed
globus-tracker.comview history2010-03-29 04:30:51Closed
goem.orgview history2010-03-29 03:56:07Closed
gormogon.comview history2010-03-29 04:25:05Open
greek-tracker.comview history2010-03-29 03:51:06Closed
grimetorrent.comview history2010-03-29 04:28:15Closed
grtorrent.comview history2010-03-29 04:12:08Closed
guiks.netview history2010-03-29 04:05:04Closed
h264torrents.comview history2010-03-29 03:57:01Closed
h33t.comview history2010-03-29 03:51:06Open
hd-bits.roview history2010-03-29 04:18:09Closed
hd-torrents.orgview history2010-03-29 04:05:05Closed
hdbits.orgview history2010-03-29 04:12:07Closed
hdchina.orgview history2010-03-29 03:59:37Closed
hdfrench.comview history2010-03-29 04:09:01Closed
hdme.euview history2010-03-29 03:55:09Open
hdpre.comview history2010-03-29 04:12:09Closed
hdsource.bizview history2010-03-29 03:49:13Closed
hdstar.orgview history2010-03-29 03:51:02Closed
hdvnbits.orgview history2010-03-29 03:56:03Closed
heaventracker.orgview history2010-03-29 03:57:02Closed
hermeticos.orgview history2010-03-29 04:25:12Closed
horrorcharnel.kicks-ass.orgview history2010-03-29 03:58:05Closed
hungercity.orgview history2010-03-29 04:31:05Open
ifyounotknow.comview history2010-03-29 03:58:07Closed
ilovetorrents.comview history2010-03-29 03:56:06Open
indeep.bizview history2010-03-29 03:56:08Closed
indietorrents.comview history2010-03-29 04:00:14Closed
iplay.roview history2010-03-29 03:59:03Closed
ipodnova.tvview history2010-03-29 04:04:12Closed
iptorrents.comview history2010-03-29 03:51:06Closed
joompalace.comview history2010-03-29 03:57:04Closed
karagarga.netview history2010-03-29 04:17:07Closed
killawaves.netview history2010-03-29 04:05:05Closed
kinozal.wsview history2010-03-29 04:28:16Open
kludd.comview history2010-03-29 03:55:11Closed
lasttorrents.orgview history2010-03-29 04:32:02Open
leecherslair.comview history2010-03-29 04:18:08Closed
libble.comview history2010-03-29 04:25:11Closed
libitina.netview history2010-03-29 04:18:11Closed
linuxmafia.netview history2010-03-29 04:22:07Offline
linuxtracker.orgview history2010-03-29 04:22:24Closed
lostfilm.tvview history2010-03-29 04:00:07Open
magiciantorrents.comview history2010-03-29 03:55:14Closed
masterstb.comview history2010-03-29 03:56:12Closed
mazetorrents.netview history2010-03-29 04:17:07Offline
medioteka.comview history2010-03-29 04:17:07Closed
mega-bits.comview history2010-03-29 03:51:52Closed
mentol.roview history2010-03-29 04:12:04Closed
metal.iplay.roview history2010-03-29 04:18:03Closed
metalbits.orgview history2010-03-29 04:00:02Closed
midnight-scene.comview history2010-03-29 03:58:06Closed
midnight-torrents.comview history2010-03-29 04:31:05Closed
mma-central.org.ukview history2010-03-29 03:56:05Closed
mma-tracker.netview history2010-03-29 03:50:43Closed
mp3nerds.orgview history2010-03-29 04:18:07Closed
mucis-vid.comview history2010-03-29 03:56:06Closed
musicplace.lvview history2010-03-29 04:05:04Closed
mytorrent.tvview history2010-03-29 03:57:07Closed
norbits.netview history2010-03-29 04:12:05Closed
nordic-t.orgview history2010-03-29 03:55:02Closed
nordicbits.orgview history2010-03-29 04:18:07Offline
novaro.infoview history2010-03-29 03:49:16Closed
novaro.infoview history2010-03-29 03:55:02Closed
noviteti.comview history2010-03-29 04:15:05Offline
ntorrents.netview history2010-03-29 03:59:08Closed
nutorrent.comview history2010-03-29 04:25:12Open
opennetwork.roview history2010-03-29 04:08:49Closed
overtopropetorrents.comview history2010-03-29 04:00:14Closed
ozone-torrents.orgview history2010-03-29 04:32:00Closed
Pedros btmusicview history2010-03-29 04:08:54Closed
pianosheets.orgview history2010-03-29 03:49:17Closed
pinkytorrents.comview history2010-03-29 03:56:08Open
piranha.excom.usview history2010-03-29 04:08:07Open
Pirate The Net (PtN)view history2010-03-29 03:49:15Closed
piratebits.orgview history2010-03-29 04:09:01Closed
piratefiles.seview history2010-03-29 04:25:05Closed
piratetorrents.nuview history2010-03-29 03:56:04Closed
pisexy.orgview history2010-03-29 04:01:06Closed
polishbytes.netview history2010-03-29 04:31:55Open
polishtracker.orgview history2010-03-29 03:56:09Closed
pornbay.orgview history2010-03-29 03:57:12Closed
PotUKview history2010-03-29 04:08:54Closed
powerscene.orgview history2010-03-29 03:57:11Closed
pretome.netview history2010-03-29 04:32:01Closed
proaudiotorrents.orgview history2010-03-29 04:15:14Closed
psytorrents.infoview history2010-03-29 03:49:08Closed
ptfiles.orgview history2010-03-29 04:18:09Closed
punkhc.dyndns.orgview history2010-03-29 04:01:09Closed
puretna.comview history2010-03-29 04:05:06Open
pussytorrents.orgview history2010-03-29 03:52:02Open
rapthe.netview history2010-03-29 04:12:09Closed
rarbg.comview history2010-03-29 03:58:11Open
reload-paradise.netview history2010-03-29 04:00:07Closed
revolutiontt.netview history2010-03-29 03:56:07Closed
rmvbustersview history2010-03-29 04:15:08Open
rmvbusters.plview history2010-03-29 03:56:05Open
scaliwags.orgview history2010-03-29 03:59:04Closed
scene-gold.infoview history2010-03-29 04:17:08Offline
scene-inspired.comview history2010-03-29 03:51:07Open
sceneaccess.orgview history2010-03-29 03:55:09Closed
scenebytes.clview history2010-03-29 04:22:20Closed
scenehd.orgview history2010-03-29 04:28:09Closed
sceneleech.orgview history2010-03-29 03:57:05Closed
SceneLife (ScL)view history2010-03-29 04:00:08Closed
scenetorrents.orgview history2010-03-29 04:12:05Closed
scenetuga.orgview history2010-03-29 03:51:04Closed
sciencehd.netview history2010-03-29 04:00:15Closed
scifitorrents.netview history2010-03-29 03:56:10Closed
secret-cinema.netview history2010-03-29 04:28:13Closed
seedgames.orgview history2010-03-29 04:18:16Closed
seedmore.orgview history2010-03-29 03:56:11Closed
sharetorrents.plview history2010-03-29 04:01:13Closed
sharing-torrents.comview history2010-03-29 03:58:14Closed
slosoul.netview history2010-03-29 03:51:00Closed
snowtigers.netview history2010-03-29 03:49:43Closed
softmp3.orgview history2010-03-29 04:18:02Closed
softmupparna.netview history2010-03-29 04:31:05Closed
sounddamage.comview history2010-03-29 03:49:14Closed
spanishtracker.comview history2010-03-29 04:25:07Open
spank-d-monkey.comview history2010-03-29 04:17:09Closed
special.pwtorrents.netview history2010-03-29 03:56:06Closed
speed.cdview history2010-03-29 03:52:02Closed
spiryt.ath.cxview history2010-03-29 04:12:07Closed
sport-scene.netview history2010-03-29 03:55:15Closed
sportbit.orgview history2010-03-29 04:25:08Closed
sportleech.netview history2010-03-29 04:28:08Closed
stmusic.orgview history2010-03-29 04:05:04Open
supertorrents.orgview history2010-03-29 04:05:08Open
swebits.orgview history2010-03-29 04:15:05Closed
sweninjaz.orgview history2010-03-29 04:32:02Closed
swep2p.orgview history2010-03-29 03:51:52Closed
swepiracy.orgview history2010-03-29 04:05:07Open
swetorrents.no-ip.orgview history2010-03-29 04:31:05Closed
taiphimhd.comview history2010-03-29 03:55:07Closed
tastetherainbow.wsview history2010-03-29 04:00:04Closed
teamofgreekz.comview history2010-03-29 04:18:03Closed
tehconnection.euview history2010-03-29 04:28:06Closed
the-zomb.comview history2010-03-29 04:08:55Open
thebox.bzview history2010-03-29 03:51:06Open
thedvdclub.orgview history2010-03-29 04:25:07Open
thegt.netview history2010-03-29 04:31:58Closed
themixingbowl.orgview history2010-03-29 04:22:25Closed
theoccult.bzview history2010-03-29 03:51:02Closed
thepeerhub.comview history2010-03-29 04:00:12Open
theplace.bzview history2010-03-29 04:08:56Closed
thepokerbay.orgview history2010-03-29 03:59:37Open
thevault.bzview history2010-03-29 03:59:39Closed
titaniumtorrents.netview history2010-03-29 04:18:11Offline
tmtorrents.orgview history2010-03-29 03:49:12Closed
topbytes.netview history2010-03-29 03:49:08Closed
topbytes.netview history2010-03-29 04:05:05Closed
tophos.orgview history2010-03-29 03:58:09Closed
torrent-damage.netview history2010-03-29 03:50:45Closed
torrent.itview history2010-03-29 04:25:12Closed
torrent411.comview history2010-03-29 04:15:08Open
torrentbits.roview history2010-03-29 04:31:57Closed
torrentbully.comview history2010-03-29 03:55:08Closed
torrentdownloads.netview history2010-03-29 04:15:05Open
torrentgaming.netview history2010-03-29 04:28:18Closed
torrentgeeks.comview history2010-03-29 03:51:02Offline
torrenthr.orgview history2010-03-29 04:21:10Open
torrentkings.orgview history2010-03-29 03:49:05Closed
torrentleech.orgview history2010-03-29 04:01:09Closed
torrentseed.orgview history2010-03-29 03:56:10Closed
torrentsforall.netview history2010-03-29 04:15:07Open
torrentsmd.comview history2010-03-29 04:00:09Closed
torrentvault.orgview history2010-03-29 03:49:12Closed
torrentzilla.orgview history2010-03-29 03:57:04Open
torrentzone.netview history2010-03-29 04:18:03Open
totaltorrents.comview history2010-03-29 04:05:05Closed
trancebits.comview history2010-03-29 04:25:09Closed
trancebooster.netview history2010-03-29 04:05:03Closed
trancetraffic.comview history2010-03-29 04:12:10Closed
tri-tavern.comview history2010-03-29 04:17:07Closed
tribalmixes.comview history2010-03-29 04:15:07Open
tugaleech.comview history2010-03-29 03:59:05Closed
tunebully.comview history2010-03-29 04:25:09Closed
tv.torrents.roview history2010-03-29 03:58:06Closed
tvtorrents.comview history2010-03-29 04:18:05Open
ugstorrents.comview history2010-03-29 04:28:11Closed
uknova.comview history2010-03-29 04:22:26Closed
underground-gamer.comview history2010-03-29 04:17:07Open
victorrent.netview history2010-03-29 04:01:09Closed
vortexnetwork.orgview history2010-03-29 03:56:08Offline
waffles.fmview history2010-03-29 03:56:11Closed
wantedfiles.roview history2010-03-29 04:18:06Open
warezbros.orgview history2010-03-29 04:08:59Closed
what.cdview history2010-03-29 04:22:27Closed
wild-bytes.orgview history2010-03-29 04:12:07Closed
wolfbits.orgview history2010-03-29 04:22:07Closed
worldboxingvideoarchive.comview history2010-03-29 04:05:06Open
www.bt-pt.netview history2010-03-29 03:56:05Open
www.llywot.comview history2010-03-29 03:59:38Closed
xbitz.orgview history2010-03-29 04:18:14Open
xider.huview history2010-03-29 04:05:02Open
xtremespeeds.netview history2010-03-29 04:01:04Closed
xtremewrestlingtorrents.netview history2010-03-29 03:51:05Closed
xtremezone.roview history2010-03-29 03:58:08Closed
yuwabits.netview history2010-03-29 04:05:07Open
zanettetorrent.comview history2010-03-29 04:00:10Open
zinebytes.orgview history2010-03-29 04:25:10Closed
+
+


+ +--> + +
+ + + + + + diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/api.html b/node_modules/jsdom/node_modules/htmlparser/testdata/api.html new file mode 100644 index 0000000..e7a71c4 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/api.html @@ -0,0 +1,3311 @@ + + + + + node(1) -- evented I/O for V8 JavaScript + + + + + +
+
Node v0.1.99
+ +
+
+
+

node(1)

+ +
    +
  1. node(1)
  2. + +
  3. +
  4. node(1)
  5. +
+

NAME

+

node -- evented I/O for V8 JavaScript

+ +

Synopsis

+ +

An example of a web server written with Node which responds with 'Hello +World':

+ +
var sys = require('sys'),
+  http = require('http');
+
+http.createServer(function (request, response) {
+  response.writeHead(200, {'Content-Type': 'text/plain'});
+  response.end('Hello World\n');
+}).listen(8124);
+
+sys.puts('Server running at http://127.0.0.1:8124/');
+
+ +

To run the server, put the code into a file called example.js and execute +it with the node program

+ +
> node example.js
+Server running at http://127.0.0.1:8124/
+
+ +

All of the examples in the documentation can be run similarly.

+ +

Standard Modules

+ +

Node comes with a number of modules that are compiled in to the process, +most of which are documented below. The most common way to use these modules +is with require('name') and then assigning the return value to a local +variable with the same name as the module.

+ +

Example:

+ +
var sys = require('sys');
+
+ +

It is possible to extend node with other modules. See 'Modules'

+ +

Buffers

+ +

Pure Javascript is Unicode friendly but not nice to binary data. When +dealing with TCP streams or the file system, it's necessary to handle octet +streams. Node has several strategies for manipulating, creating, and +consuming octet streams.

+ +

Raw data is stored in instances of the Buffer class. A Buffer is similar +to an array of integers but corresponds to a raw memory allocation outside +the V8 heap. A Buffer cannot be resized. +Access the class with require('buffer').Buffer.

+ +

Converting between Buffers and JavaScript string objects requires an explicit encoding +method. Node supports 3 string encodings: UTF-8 ('utf8'), ASCII ('ascii'), and +Binary ('binary').

+ +
    +
  • 'ascii' - for 7 bit ASCII data only. This encoding method is very fast, and will +strip the high bit if set.

  • +
  • 'binary' - for 8 bit binary data such as images.

  • +
  • 'utf8' - Unicode characters. Many web pages and other document formats use UTF-8.

  • +
+ + +

new Buffer(size)

+ +

Allocates a new buffer of size octets.

+ +

new Buffer(array)

+ +

Allocates a new buffer using an array of octets.

+ +

new Buffer(str, encoding = 'utf8')

+ +

Allocates a new buffer containing the given str.

+ +

buffer.write(string, encoding, offset)

+ +

Writes string to the buffer at offset using the given encoding. Returns +number of octets written. If buffer did not contain enough space to fit +the entire string it will write a partial amount of the string. In the case +of 'utf8' encoding, the method will not write partial characters.

+ +

Example: write a utf8 string into a buffer, then print it

+ +
var sys = require('sys'),
+  Buffer = require('buffer').Buffer,
+  buf = new Buffer(256),
+  len;
+
+len = buf.write('\u00bd + \u00bc = \u00be', 'utf8', 0);
+sys.puts(len + " bytes: " + buf.toString('utf8', 0, len));
+
+// 12 bytes: ½ + ¼ = ¾
+
+ +

buffer.toString(encoding, start, end)

+ +

Decodes and returns a string from buffer data encoded with encoding +beginning at start and ending at end.

+ +

See buffer.write() example, above.

+ +

buffer[index]

+ +

Get and set the octet at index. The values refer to individual bytes, +so the legal range is between 0x00 and 0xFF hex or 0 and 255.

+ +

Example: copy an ASCII string into a buffer, one byte at a time:

+ +
var sys = require('sys'),
+  Buffer = require('buffer').Buffer,
+  str = "node.js",
+  buf = new Buffer(str.length),
+  i;
+
+for (i = 0; i < str.length ; i += 1) {
+  buf[i] = str.charCodeAt(i);
+}
+
+sys.puts(buf);
+
+// node.js
+
+ +

Buffer.byteLength(string, encoding)

+ +

Gives the actual byte length of a string. This is not the same as +String.prototype.length since that returns the number of characters in a +string.

+ +

Example:

+ +
var sys = require('sys'),
+  Buffer = require('buffer').Buffer,
+  str = '\u00bd + \u00bc = \u00be';
+
+sys.puts(str + ": " + str.length + " characters, " + 
+  Buffer.byteLength(str, 'utf8') + " bytes");
+
+// ½ + ¼ = ¾: 9 characters, 12 bytes
+
+ +

buffer.length

+ +

The size of the buffer in bytes. Note that this is not necessarily the size +of the contents. length refers to the amount of memory allocated for the +buffer object. It does not change when the contents of the buffer are changed.

+ +
var sys = require('sys'),
+  Buffer = require('buffer').Buffer,
+  buf = new Buffer(1234);
+
+sys.puts(buf.length);
+buf.write("some string", "ascii", 0);
+sys.puts(buf.length);
+
+// 1234
+// 1234
+
+ +

buffer.copy(targetBuffer, targetStart, sourceStart, sourceEnd)

+ +

Does a memcpy() between buffers.

+ +

Example: build two Buffers, then copy buf1 from byte 16 through byte 20 +into buf2, starting at the 8th byte in buf2.

+ +
var sys = require('sys'),
+  Buffer = require('buffer').Buffer,
+  buf1 = new Buffer(26),
+  buf2 = new Buffer(26),
+  i;
+
+for (i = 0 ; i < 26 ; i += 1) {
+  buf1[i] = i + 97; // 97 is ASCII a
+  buf2[i] = 33; // ASCII !
+}
+
+buf1.copy(buf2, 8, 16, 20);
+sys.puts(buf2.toString('ascii', 0, 25));
+
+// !!!!!!!!qrst!!!!!!!!!!!!!
+
+ +

buffer.slice(start, end)

+ +

Returns a new buffer which references the +same memory as the old, but offset and cropped by the start and end +indexes.

+ +

Modifying the new buffer slice will modify memory in the original buffer!

+ +

Example: build a Buffer with the ASCII alphabet, take a slice, then modify one byte +from the original Buffer.

+ +
var sys = require('sys'),
+  Buffer = require('buffer').Buffer,
+  buf1 = new Buffer(26), buf2,
+  i;
+
+for (i = 0 ; i < 26 ; i += 1) {
+  buf1[i] = i + 97; // 97 is ASCII a
+}
+
+buf2 = buf1.slice(0, 3);
+sys.puts(buf2.toString('ascii', 0, buf2.length));
+buf1[0] = 33;
+sys.puts(buf2.toString('ascii', 0, buf2.length));
+
+// abc
+// !bc
+
+ +

EventEmitter

+ +

Many objects in Node emit events: a TCP server emits an event each time +there is a stream, a child process emits an event when it exits. All +objects which emit events are instances of events.EventEmitter.

+ +

Events are represented by a camel-cased string. Here are some examples: +'stream', 'data', 'messageBegin'.

+ +

Functions can be then be attached to objects, to be executed when an event +is emitted. These functions are called listeners.

+ +

require('events').EventEmitter to access the EventEmitter class.

+ +

All EventEmitters emit the event 'newListener' when new listeners are +added.

+ +

When an EventEmitter experiences an error, the typical action is to emit an +'error' event. Error events are special--if there is no handler for them +they will print a stack trace and exit the program.

+ +

Event: 'newListener'

+ +

function (event, listener) { }

+ +

This event is made any time someone adds a new listener.

+ +

Event: 'error'

+ +

function (exception) { }

+ +

If an error was encountered, then this event is emitted. This event is +special - when there are no listeners to receive the error Node will +terminate execution and display the exception's stack trace.

+ +

emitter.addListener(event, listener)

+ +

Adds a listener to the end of the listeners array for the specified event.

+ +
server.addListener('stream', function (stream) {
+  sys.puts('someone connected!');
+});
+
+ +

emitter.removeListener(event, listener)

+ +

Remove a listener from the listener array for the specified event. +Caution: changes array indices in the listener array behind the listener.

+ +

emitter.removeAllListeners(event)

+ +

Removes all listeners from the listener array for the specified event.

+ +

emitter.listeners(event)

+ +

Returns an array of listeners for the specified event. This array can be +manipulated, e.g. to remove listeners.

+ +

emitter.emit(event, arg1, arg2, ...)

+ +

Execute each of the listeners in order with the supplied arguments.

+ +

Streams

+ +

A stream is an abstract interface implemented by various objects in Node. +For example a request to an HTTP server is a stream, as is stdout. Streams +are readable, writable, or both. All streams are instances of EventEmitter.

+ +

Readable Stream

+ +

A readable stream has the following methods, members, and events.

+ +

Event: 'data'

+ +

function (data) { }

+ +

The 'data' event emits either a Buffer (by default) or a string if +setEncoding() was used.

+ +

Event: 'end'

+ +

function () { }

+ +

Emitted when the stream has received an EOF (FIN in TCP terminology). +Indicates that no more 'data' events will happen. If the stream is also +writable, it may be possible to continue writing.

+ +

Event: 'error'

+ +

function (exception) { }

+ +

Emitted if there was an error receiving data.

+ +

Event: 'close'

+ +

function () { }

+ +

Emitted when the underlying file descriptor has be closed. Not all streams +will emit this. (For example, an incoming HTTP request will not emit +'close'.)

+ +

stream.setEncoding(encoding)

+ +

Makes the data event emit a string instead of a Buffer. encoding can be +'utf8', 'ascii', or 'binary'.

+ +

stream.pause()

+ +

Pauses the incoming 'data' events.

+ +

stream.resume()

+ +

Resumes the incoming 'data' events after a pause().

+ +

stream.destroy()

+ +

Closes the underlying file descriptor. Stream will not emit any more events.

+ +

Writable Stream

+ +

A writable stream has the following methods, members, and events.

+ +

Event: 'drain'

+ +

function () { }

+ +

Emitted after a write() method was called that returned false to +indicate that it is safe to write again.

+ +

Event: 'error'

+ +

function (exception) { }

+ +

Emitted on error with the exception exception.

+ +

Event: 'close'

+ +

function () { }

+ +

Emitted when the underlying file descriptor has been closed.

+ +

stream.write(string, encoding)

+ +

Writes string with the given encoding to the stream. Returns true if +the string has been flushed to the kernel buffer. Returns false to +indicate that the kernel buffer is full, and the data will be sent out in +the future. The 'drain' event will indicate when the kernel buffer is +empty again. The encoding defaults to 'utf8'.

+ +

stream.write(buffer)

+ +

Same as the above except with a raw buffer.

+ +

stream.end()

+ +

Terminates the stream with EOF or FIN.

+ +

stream.end(string, encoding)

+ +

Sends string with the given encoding and terminates the stream with EOF +or FIN. This is useful to reduce the number of packets sent.

+ +

stream.end(buffer)

+ +

Same as above but with a buffer.

+ +

stream.destroy()

+ +

Closes the underlying file descriptor. Stream will not emit any more events.

+ +

Global Objects

+ +

These object are available in the global scope and can be accessed from anywhere.

+ +

global

+ +

The global namespace object.

+ +

process

+ +

The process object. Most stuff lives in here. See the 'process object' +section.

+ +

require()

+ +

To require modules. See the 'Modules' section.

+ +

require.paths

+ +

An array of search paths for require(). This array can be modified to add custom paths.

+ +

Example: add a new path to the beginning of the search list

+ +
var sys = require('sys');
+
+require.paths.unshift('/usr/local/node');
+sys.puts(require.paths);
+// /usr/local/node,/Users/mjr/.node_libraries
+
+ +

__filename

+ +

The filename of the script being executed. This is the absolute path, and not necessarily +the same filename passed in as a command line argument.

+ +

__dirname

+ +

The dirname of the script being executed.

+ +

Example: running node example.js from /Users/mjr

+ +
var sys = require('sys');
+sys.puts(__filename);
+sys.puts(__dirname);
+// /Users/mjr/example.js
+// /Users/mjr
+
+ +

module

+ +

A reference to the current module (of type process.Module). In particular +module.exports is the same as the exports object. See src/process.js +for more information.

+ +

process

+ +

The process object is a global object and can be accessed from anywhere. +It is an instance of EventEmitter.

+ +

Event: 'exit'

+ +

function () {}

+ +

Emitted when the process is about to exit. This is a good hook to perform +constant time checks of the module's state (like for unit tests). The main +event loop will no longer be run after the 'exit' callback finishes, so +timers may not be scheduled.

+ +

Example of listening for exit:

+ +
var sys = require('sys');
+
+process.addListener('exit', function () {
+  process.nextTick(function () {
+   sys.puts('This will not run');
+  });
+  sys.puts('About to exit.');
+});
+
+ +

Event: 'uncaughtException'

+ +

function (err) { }

+ +

Emitted when an exception bubbles all the way back to the event loop. If a +listener is added for this exception, the default action (which is to print +a stack trace and exit) will not occur.

+ +

Example of listening for uncaughtException:

+ +
var sys = require('sys');
+
+process.addListener('uncaughtException', function (err) {
+  sys.puts('Caught exception: ' + err);
+});
+
+setTimeout(function () {
+  sys.puts('This will still run.');
+}, 500);
+
+// Intentionally cause an exception, but don't catch it.
+nonexistentFunc();
+sys.puts('This will not run.');
+
+ +

Note that uncaughtException is a very crude mechanism for exception +handling. Using try / catch in your program will give you more control over +your program's flow. Especially for server programs that are designed to +stay running forever, uncaughtException can be a useful safety mechanism.

+ +

Signal Events

+ +

function () {}

+ +

Emitted when the processes receives a signal. See sigaction(2) for a list of +standard POSIX signal names such as SIGINT, SIGUSR1, etc.

+ +

Example of listening for SIGINT:

+ +
var sys = require('sys'),
+    stdin = process.openStdin();
+
+process.addListener('SIGINT', function () {
+  sys.puts('Got SIGINT.  Press Control-D to exit.');
+});
+
+ +

An easy way to send the SIGINT signal is with Control-C in most terminal +programs.

+ +

process.stdout

+ +

A writable stream to stdout.

+ +

Example: the definition of sys.puts

+ +
exports.puts = function (d) {
+  process.stdout.write(d + '\n');
+};
+
+ +

process.openStdin()

+ +

Opens the standard input stream, returns a readable stream.

+ +

Example of opening standard input and listening for both events:

+ +
var stdin = process.openStdin();
+
+stdin.setEncoding('utf8');
+
+stdin.addListener('data', function (chunk) {
+  process.stdout.write('data: ' + chunk);
+});
+
+stdin.addListener('end', function () {
+  process.stdout.write('end');
+});
+
+ +

process.argv

+ +

An array containing the command line arguments. The first element will be +'node', the second element will be the name of the JavaScript file. The +next elements will be any additional command line arguments.

+ +
// print process.argv
+var sys = require('sys');
+
+process.argv.forEach(function (val, index, array) {
+  sys.puts(index + ': ' + val);
+});
+
+ +

This will generate:

+ +
$ node process-2.js one two=three four
+0: node
+1: /Users/mjr/work/node/process-2.js
+2: one
+3: two=three
+4: four
+
+ +

process.chdir(directory)

+ +

Changes the current working directory of the process or throws an exception if that fails.

+ +
var sys = require('sys');
+
+sys.puts('Starting directory: ' + process.cwd());
+try {
+  process.chdir('/tmp');
+  sys.puts('New directory: ' + process.cwd());
+}
+catch (err) {
+  sys.puts('chdir: ' + err);
+}
+
+ +

process.compile(code, filename)

+ +

Similar to eval except that you can specify a filename for better +error reporting and the code cannot see the local scope. The value of filename +will be used as a filename if a stack trace is generated by the compiled code.

+ +

Example of using process.compile and eval to run the same code:

+ +
var sys = require('sys'),
+    localVar = 123,
+    compiled, evaled;
+
+compiled = process.compile('localVar = 1;', 'myfile.js');
+sys.puts('localVar: ' + localVar + ', compiled: ' + compiled);
+evaled = eval('localVar = 1;');
+sys.puts('localVar: ' + localVar + ', evaled: ' + evaled);
+
+// localVar: 123, compiled: 1
+// localVar: 1, evaled: 1
+
+ +

process.compile does not have access to the local scope, so localVar is unchanged. +eval does have access to the local scope, so localVar is changed.

+ +

In case of syntax error in code, process.compile exits node.

+ +

See also: Script

+ +

process.cwd()

+ +

Returns the current working directory of the process.

+ +
require('sys').puts('Current directory: ' + process.cwd());
+
+ +

process.env

+ +

An object containing the user environment. See environ(7).

+ +

process.exit(code)

+ +

Ends the process with the specified code. If omitted, exit uses the +'success' code 0.

+ +

To exit with a 'failure' code:

+ +
process.exit(1);
+
+ +

The shell that executed node should see the exit code as 1.

+ +

process.getgid(), process.setgid(id)

+ +

Gets/sets the group identity of the process. (See setgid(2).) This is the numerical group id, not the group name.

+ +
var sys = require('sys');
+
+sys.puts('Current gid: ' + process.getgid());
+try {
+  process.setgid(501);
+  sys.puts('New gid: ' + process.getgid());
+}
+catch (err) {
+  sys.puts('Failed to set gid: ' + err);
+}
+
+ +

process.getuid(), process.setuid(id)

+ +

Gets/sets the user identity of the process. (See setuid(2).) This is the numerical userid, not the username.

+ +
var sys = require('sys');
+
+sys.puts('Current uid: ' + process.getuid());
+try {
+  process.setuid(501);
+  sys.puts('New uid: ' + process.getuid());
+}
+catch (err) {
+  sys.puts('Failed to set uid: ' + err);
+}
+
+ +

process.version

+ +

A compiled-in property that exposes NODE_VERSION.

+ +
require('sys').puts('Version: ' + process.version);
+
+ +

process.installPrefix

+ +

A compiled-in property that exposes NODE_PREFIX.

+ +
require('sys').puts('Prefix: ' + process.installPrefix);
+
+ +

process.kill(pid, signal)

+ +

Send a signal to a process. pid is the process id and signal is the +string describing the signal to send. Signal names are strings like +'SIGINT' or 'SIGUSR1'. If omitted, the signal will be 'SIGINT'. +See kill(2) for more information.

+ +

Note that just because the name of this function is process.kill, it is +really just a signal sender, like the kill system call. The signal sent +may do something other than kill the target process.

+ +

Example of sending a signal to yourself:

+ +
var sys = require('sys');
+
+process.addListener('SIGHUP', function () {
+  sys.puts('Got SIGHUP signal.');
+});
+
+setTimeout(function () {
+  sys.puts('Exiting.');
+  process.exit(0);
+}, 100);
+
+process.kill(process.pid, 'SIGHUP');
+
+ +

process.pid

+ +

The PID of the process.

+ +
require('sys').puts('This process is pid ' + process.pid);
+
+ +

process.platform

+ +

What platform you're running on. 'linux2', 'darwin', etc.

+ +
require('sys').puts('This platform is ' + process.platform);
+
+ +

process.memoryUsage()

+ +

Returns an object describing the memory usage of the Node process.

+ +
var sys = require('sys');
+
+sys.puts(sys.inspect(process.memoryUsage()));
+
+ +

This will generate:

+ +
{ rss: 4935680
+, vsize: 41893888
+, heapTotal: 1826816
+, heapUsed: 650472
+}
+
+ +

heapTotal and heapUsed refer to V8's memory usage.

+ +

process.nextTick(callback)

+ +

On the next loop around the event loop call this callback. +This is not a simple alias to setTimeout(fn, 0), it's much more +efficient.

+ +
var sys = require('sys');
+
+process.nextTick(function () {
+  sys.puts('nextTick callback');
+});
+
+ +

process.umask(mask)

+ +

Sets or read the process's file mode creation mask. Child processes inherit +the mask from the parent process. Returns the old mask if mask argument is +given, otherwise returns the current mask.

+ +
var sys = require('sys'),
+    oldmask, newmask = 0644;
+
+oldmask = process.umask(newmask);
+sys.puts('Changed umask from: ' + oldmask.toString(8) +
+         ' to ' + newmask.toString(8));
+
+ +

sys

+ +

These functions are in the module 'sys'. Use require('sys') to access +them.

+ +

sys.puts(string)

+ +

Outputs string and a trailing newline to stdout.

+ +
require('sys').puts('String with a newline');
+
+ +

sys.print(string)

+ +

Like puts() but without the trailing newline.

+ +
require('sys').print('String with no newline');
+
+ +

sys.debug(string)

+ +

A synchronous output function. Will block the process and +output string immediately to stderr.

+ +
require('sys').debug('message on stderr');
+
+ +

sys.log(string)

+ +

Output with timestamp on stdout.

+ +
require('sys').log('Timestmaped message.');
+
+ +

sys.inspect(object, showHidden, depth)

+ +

Return a string representation of object, which is useful for debugging.

+ +

If showHidden is true, then the object's non-enumerable properties will be +shown too.

+ +

If depth is provided, it tells inspect how many times to recurse while +formatting the object. This is useful for inspecting large complicated objects.

+ +

The default is to only recurse twice. To make it recurse indefinitely, pass +in null for depth.

+ +

Example of inspecting all properties of the sys object:

+ +
var sys = require('sys');
+
+sys.puts(sys.inspect(sys, true, null));
+
+ +

Timers

+ +

setTimeout(callback, delay, [arg, ...])

+ +

To schedule execution of callback after delay milliseconds. Returns a +timeoutId for possible use with clearTimeout().

+ +

clearTimeout(timeoutId)

+ +

Prevents a timeout from triggering.

+ +

setInterval(callback, delay, [arg, ...])

+ +

To schedule the repeated execution of callback every delay milliseconds. +Returns a intervalId for possible use with clearInterval().

+ +

Optionally, you can also pass arguments to the callback.

+ +

clearInterval(intervalId)

+ +

Stops a interval from triggering.

+ +

Child Processes

+ +

Node provides a tri-directional popen(3) facility through the ChildProcess +class.

+ +

It is possible to stream data through the child's stdin, stdout, and +stderr in a fully non-blocking way.

+ +

To create a child process use require('child_process').spawn().

+ +

Child processes always have three streams associated with them. child.stdin, +child.stdout, and child.stderr.

+ +

ChildProcess is an EventEmitter.

+ +

Event: 'exit'

+ +

function (code, signal) {}

+ +

This event is emitted after the child process ends. If the process terminated +normally, code is the final exit code of the process, otherwise null. If +the process terminated due to receipt of a signal, signal is the string name +of the signal, otherwise null.

+ +

After this event is emitted, the 'output' and 'error' callbacks will no +longer be made.

+ +

See waitpid(2).

+ +

child_process.spawn(command, args, env)

+ +

Launches a new process with the given command, command line arguments, and +environment variables. If omitted, args defaults to an empty Array, and env +defaults to process.env.

+ +

Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:

+ +
var sys   = require('sys'),
+    spawn = require('child_process').spawn,
+    ls    = spawn('ls', ['-lh', '/usr']);
+
+ls.stdout.addListener('data', function (data) {
+  sys.print('stdout: ' + data);
+});
+
+ls.stderr.addListener('data', function (data) {
+  sys.print('stderr: ' + data);
+});
+
+ls.addListener('exit', function (code) {
+  sys.puts('child process exited with code ' + code);
+});
+
+ +

Example of checking for failed exec:

+ +
var sys   = require('sys'),
+    spawn = require('child_process').spawn,
+    child = spawn('bad_command');
+
+child.stderr.addListener('data', function (data) {
+  if (/^execvp\(\)/.test(data.asciiSlice(0,data.length))) {
+    sys.puts('Failed to start child process.');
+  }
+});
+
+ +

See also: child_process.exec()

+ +

child.kill(signal)

+ +

Send a signal to the child process. If no argument is given, the process will +be sent 'SIGTERM'. See signal(7) for a list of available signals.

+ +
var sys   = require('sys'),
+    spawn = require('child_process').spawn,
+    grep  = spawn('grep', ['ssh']);
+
+grep.addListener('exit', function (code, signal) {
+  sys.puts('child process terminated due to receipt of signal '+signal);
+});
+
+// send SIGHUP to process
+grep.kill('SIGHUP');
+
+ +

Note that while the function is called kill, the signal delivered to the child +process may not actually kill it. kill really just sends a signal to a process.

+ +

See kill(2)

+ +

child.pid

+ +

The PID of the child process.

+ +

Example:

+ +
var sys   = require('sys'),
+    spawn = require('child_process').spawn,
+    grep  = spawn('grep', ['ssh']);
+
+sys.puts('Spawned child pid: ' + grep.pid);
+grep.stdin.end();
+
+ +

child.stdin.write(data, encoding)

+ +

Write data to the child process's stdin. The second argument is optional and +specifies the encoding: possible values are 'utf8', 'ascii', and +'binary'.

+ +

Example: A very elaborate way to run 'ps ax | grep ssh'

+ +
var sys   = require('sys'),
+    spawn = require('child_process').spawn,
+    ps    = spawn('ps', ['ax']),
+    grep  = spawn('grep', ['ssh']);
+
+ps.stdout.addListener('data', function (data) {
+  grep.stdin.write(data);
+});
+
+ps.stderr.addListener('data', function (data) {
+  sys.print('ps stderr: ' + data);
+});
+
+ps.addListener('exit', function (code) {
+  if (code !== 0) {
+    sys.puts('ps process exited with code ' + code);
+  }
+  grep.stdin.end();
+});
+
+grep.stdout.addListener('data', function (data) {
+  sys.print(data);
+});
+
+grep.stderr.addListener('data', function (data) {
+  sys.print('grep stderr: ' + data);
+});
+
+grep.addListener('exit', function (code) {
+  if (code !== 0) {
+    sys.puts('grep process exited with code ' + code);
+  }
+});
+
+ +

child.stdin.end()

+ +

Closes the child process's stdin stream. This often causes the child process to terminate.

+ +

Example:

+ +
var sys   = require('sys'),
+    spawn = require('child_process').spawn,
+    grep  = spawn('grep', ['ssh']);
+
+grep.addListener('exit', function (code) {
+  sys.puts('child process exited with code ' + code);
+});
+
+grep.stdin.end();
+
+ +

child_process.exec(command, [options, ] callback)

+ +

High-level way to execute a command as a child process, buffer the +output, and return it all in a callback.

+ +
var sys   = require('sys'),
+    exec  = require('child_process').exec,
+    child;
+
+child = exec('cat *.js bad_file | wc -l', 
+  function (error, stdout, stderr) {
+    sys.print('stdout: ' + stdout);
+    sys.print('stderr: ' + stderr);
+    if (error !== null) {
+      sys.puts('exec error: ' + error);
+    }
+  });
+
+ +

The callback gets the arguments (error, stdout, stderr). On success, error +will be null. On error, error will be an instance of Error and err.code +will be the exit code of the child process, and err.signal will be set to the +signal that terminated the process.

+ +

There is a second optional argument to specify several options. The default options are

+ +
{ encoding: 'utf8'
+, timeout: 0
+, maxBuffer: 200*1024
+, killSignal: 'SIGKILL'
+}
+
+ +

If timeout is greater than 0, then it will kill the child process +if it runs longer than timeout milliseconds. The child process is killed with +killSignal (default: 'SIGKILL'). maxBuffer specifies the largest +amount of data allowed on stdout or stderr - if this value is exceeded then +the child process is killed.

+ +

Script

+ +

Script class compiles and runs JavaScript code. You can access this class with:

+ +
var Script = process.binding('evals').Script;
+
+ +

New JavaScript code can be compiled and run immediately or compiled, saved, and run later.

+ +

Script.runInThisContext(code, filename)

+ +

Similar to process.compile. Script.runInThisContext compiles code as if it were loaded from filename, +runs it and returns the result. Running code does not have access to local scope. filename is optional.

+ +

Example of using Script.runInThisContext and eval to run the same code:

+ +
var sys = require('sys'),
+    localVar = 123,
+    usingscript, evaled,
+    Script = process.binding('evals').Script;
+
+usingscript = Script.runInThisContext('localVar = 1;',
+  'myfile.js');
+sys.puts('localVar: ' + localVar + ', usingscript: ' +
+  usingscript);
+evaled = eval('localVar = 1;');
+sys.puts('localVar: ' + localVar + ', evaled: ' +
+  evaled);
+
+// localVar: 123, usingscript: 1
+// localVar: 1, evaled: 1
+
+ +

Script.runInThisContext does not have access to the local scope, so localVar is unchanged. +eval does have access to the local scope, so localVar is changed.

+ +

In case of syntax error in code, Script.runInThisContext emits the syntax error to stderr +and throws.an exception.

+ +

Script.runInNewContext(code, sandbox, filename)

+ +

Script.runInNewContext compiles code to run in sandbox as if it were loaded from filename, +then runs it and returns the result. Running code does not have access to local scope and +the object sandbox will be used as the global object for code. +sandbox and filename are optional.

+ +

Example: compile and execute code that increments a global variable and sets a new one. +These globals are contained in the sandbox.

+ +
var sys = require('sys'),
+    Script = process.binding('evals').Script,
+    sandbox = {
+      animal: 'cat',
+      count: 2
+    };
+
+Script.runInNewContext(
+  'count += 1; name = "kitty"', sandbox, 'myfile.js');
+sys.puts(sys.inspect(sandbox));
+
+// { animal: 'cat', count: 3, name: 'kitty' }
+
+ +

Note that running untrusted code is a tricky business requiring great care. To prevent accidental +global variable leakage, Script.runInNewContext is quite useful, but safely running untrusted code +requires a separate process.

+ +

In case of syntax error in code, Script.runInThisContext emits the syntax error to stderr +and throws an exception.

+ +

new Script(code, filename)

+ +

new Script compiles code as if it were loaded from filename, +but does not run it. Instead, it returns a Script object representing this compiled code. +This script can be run later many times using methods below. +The returned script is not bound to any global object. +It is bound before each run, just for that run. filename is optional.

+ +

In case of syntax error in code, new Script emits the syntax error to stderr +and throws an exception.

+ +

script.runInThisContext()

+ +

Similar to Script.runInThisContext (note capital 'S'), but now being a method of a precompiled Script object. +script.runInThisContext runs the code of script and returns the result. +Running code does not have access to local scope, but does have access to the global object +(v8: in actual context).

+ +

Example of using script.runInThisContext to compile code once and run it multiple times:

+ +
var sys = require('sys'),
+    Script = process.binding('evals').Script,
+    scriptObj, i;
+
+globalVar = 0;
+
+scriptObj = new Script('globalVar += 1', 'myfile.js');
+
+for (i = 0; i < 1000 ; i += 1) {
+  scriptObj.runInThisContext();
+}
+
+sys.puts(globalVar);
+
+// 1000
+
+ +

script.runInNewContext(sandbox)

+ +

Similar to Script.runInNewContext (note capital 'S'), but now being a method of a precompiled Script object. +script.runInNewContext runs the code of script with sandbox as the global object and returns the result. +Running code does not have access to local scope. sandbox is optional.

+ +

Example: compile code that increments a global variable and sets one, then execute this code multiple times. +These globals are contained in the sandbox.

+ +
var sys = require('sys'),
+    Script = process.binding('evals').Script,
+    scriptObj, i,
+    sandbox = {
+      animal: 'cat',
+      count: 2
+    };
+
+scriptObj = new Script(
+    'count += 1; name = "kitty"', 'myfile.js');
+
+for (i = 0; i < 10 ; i += 1) {
+  scriptObj.runInNewContext(sandbox);
+}
+
+sys.puts(sys.inspect(sandbox));
+
+// { animal: 'cat', count: 12, name: 'kitty' }
+
+ +

Note that running untrusted code is a tricky business requiring great care. To prevent accidental +global variable leakage, script.runInNewContext is quite useful, but safely running untrusted code +requires a separate process.

+ +

File System

+ +

File I/O is provided by simple wrappers around standard POSIX functions. To +use this module do require('fs'). All the methods have asynchronous and +synchronous forms.

+ +

The asynchronous form always take a completion callback as its last argument. +The arguments passed to the completion callback depend on the method, but the +first argument is always reserved for an exception. If the operation was +completed successfully, then the first argument will be null or undefined.

+ +

Here is an example of the asynchronous version:

+ +
var fs = require('fs'),
+    sys = require('sys');
+
+fs.unlink('/tmp/hello', function (err) {
+  if (err) throw err;
+  sys.puts('successfully deleted /tmp/hello');
+});
+
+ +

Here is the synchronous version:

+ +
var fs = require('fs'),
+    sys = require('sys');
+
+fs.unlinkSync('/tmp/hello')
+sys.puts('successfully deleted /tmp/hello');
+
+ +

With the asynchronous methods there is no guaranteed ordering. So the +following is prone to error:

+ +
fs.rename('/tmp/hello', '/tmp/world', function (err) {
+  if (err) throw err;
+  sys.puts('renamed complete');
+});
+fs.stat('/tmp/world', function (err, stats) {
+  if (err) throw err;
+  sys.puts('stats: ' + JSON.stringify(stats));
+});
+
+ +

It could be that fs.stat is executed before fs.rename. +The correct way to do this is to chain the callbacks.

+ +
fs.rename('/tmp/hello', '/tmp/world', function (err) {
+  if (err) throw err;
+  fs.stat('/tmp/world', function (err, stats) {
+    if (err) throw err;
+    sys.puts('stats: ' + JSON.stringify(stats));
+  });
+});
+
+ +

In busy processes, the programmer is strongly encouraged to use the +asynchronous versions of these calls. The synchronous versions will block +the entire process until they complete--halting all connections.

+ +

fs.rename(path1, path2, callback)

+ +

Asynchronous rename(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.renameSync(path1, path2)

+ +

Synchronous rename(2).

+ +

fs.truncate(fd, len, callback)

+ +

Asynchronous ftruncate(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.truncateSync(fd, len)

+ +

Synchronous ftruncate(2).

+ +

fs.chmod(path, mode, callback)

+ +

Asynchronous chmod(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.chmodSync(path, mode)

+ +

Synchronous chmod(2).

+ +

fs.stat(path, callback), fs.lstat(path, callback), fs.fstat(fd, callback)

+ +

Asynchronous stat(2), lstat(2) or fstat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. It looks like this:

+ +
{ dev: 2049
+, ino: 305352
+, mode: 16877
+, nlink: 12
+, uid: 1000
+, gid: 1000
+, rdev: 0
+, size: 4096
+, blksize: 4096
+, blocks: 8
+, atime: '2009-06-29T11:11:55Z'
+, mtime: '2009-06-29T11:11:40Z'
+, ctime: '2009-06-29T11:11:40Z' 
+}
+
+ +

See the fs.Stats section below for more information.

+ +

fs.statSync(path), fs.lstatSync(path), fs.fstatSync(fd)

+ +

Synchronous stat(2), lstat(2) or fstat(2). Returns an instance of fs.Stats.

+ +

fs.link(srcpath, dstpath, callback)

+ +

Asynchronous link(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.linkSync(dstpath, srcpath)

+ +

Synchronous link(2).

+ +

fs.symlink(linkdata, path, callback)

+ +

Asynchronous symlink(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.symlinkSync(linkdata, path)

+ +

Synchronous symlink(2).

+ +

fs.readlink(path, callback)

+ +

Asynchronous readlink(2). The callback gets two arguments (err, resolvedPath).

+ +

fs.readlinkSync(path)

+ +

Synchronous readlink(2). Returns the resolved path.

+ +

fs.realpath(path, callback)

+ +

Asynchronous realpath(2). The callback gets two arguments (err, resolvedPath).

+ +

fs.realpathSync(path)

+ +

Synchronous realpath(2). Returns the resolved path.

+ +

fs.unlink(path, callback)

+ +

Asynchronous unlink(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.unlinkSync(path)

+ +

Synchronous unlink(2).

+ +

fs.rmdir(path, callback)

+ +

Asynchronous rmdir(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.rmdirSync(path)

+ +

Synchronous rmdir(2).

+ +

fs.mkdir(path, mode, callback)

+ +

Asynchronous mkdir(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.mkdirSync(path, mode)

+ +

Synchronous mkdir(2).

+ +

fs.readdir(path, callback)

+ +

Asynchronous readdir(3). Reads the contents of a directory. +The callback gets two arguments (err, files) where files is an array of +the names of the files in the directory excluding '.' and '..'.

+ +

fs.readdirSync(path)

+ +

Synchronous readdir(3). Returns an array of filenames excluding '.' and +'..'.

+ +

fs.close(fd, callback)

+ +

Asynchronous close(2). No arguments other than a possible exception are given to the completion callback.

+ +

fs.closeSync(fd)

+ +

Synchronous close(2).

+ +

fs.open(path, flags, mode, callback)

+ +

Asynchronous file open. See open(2). Flags can be 'r', 'r+', 'w', 'w+', 'a', +or 'a+'. The callback gets two arguments (err, fd).

+ +

fs.openSync(path, flags, mode)

+ +

Synchronous open(2).

+ +

fs.write(fd, buffer, offset, length, position, callback)

+ +

Write buffer to the file specified by fd.

+ +

offset and length determine the part of the buffer to be written.

+ +

position refers to the offset from the beginning of the file where this data +should be written. If position is null, the data will be written at the +current position. +See pwrite(2).

+ +

The callback will be given two arguments (err, written) where written +specifies how many bytes were written.

+ +

fs.writeSync(fd, data, position, encoding)

+ +

Synchronous version of fs.write(). Returns the number of bytes written.

+ +

fs.read(fd, buffer, offset, length, position, callback)

+ +

Read data from the file specified by fd.

+ +

buffer is the buffer that the data will be written to.

+ +

offset is offset within the buffer where writing will start.

+ +

length is an integer specifying the number of bytes to read.

+ +

position is an integer specifying where to begin reading from in the file. +If position is null, data will be read from the current file position.

+ +

The callback is given the two arguments, (err, bytesRead).

+ +

fs.readSync(fd, buffer, offset, length, position)

+ +

Synchronous version of fs.read. Returns the number of bytesRead.

+ +

fs.readFile(filename, [encoding,] callback)

+ +

Asynchronously reads the entire contents of a file. Example:

+ +
fs.readFile('/etc/passwd', function (err, data) {
+  if (err) throw err;
+  sys.puts(data);
+});
+
+ +

The callback is passed two arguments (err, data), where data is the +contents of the file.

+ +

If no encoding is specified, then the raw buffer is returned.

+ +

fs.readFileSync(filename [, encoding])

+ +

Synchronous version of fs.readFile. Returns the contents of the filename.

+ +

If encoding is specified then this function returns a string. Otherwise it +returns a buffer.

+ +

fs.writeFile(filename, data, encoding='utf8', callback)

+ +

Asynchronously writes data to a file. Example:

+ +
fs.writeFile('message.txt', 'Hello Node', function (err) {
+  if (err) throw err;
+  sys.puts('It\'s saved!');
+});
+
+ +

fs.writeFileSync(filename, data, encoding='utf8')

+ +

The synchronous version of fs.writeFile.

+ +

fs.watchFile(filename, [options,] listener)

+ +

Watch for changes on filename. The callback listener will be called each +time the file changes.

+ +

The second argument is optional. The options if provided should be an object +containing two members a boolean, persistent, and interval, a polling +value in milliseconds. The default is {persistent: true, interval: 0}.

+ +

The listener gets two arguments the current stat object and the previous +stat object:

+ +
fs.watchFile(f, function (curr, prev) {
+  sys.puts('the current mtime is: ' + curr.mtime);
+  sys.puts('the previous mtime was: ' + prev.mtime);
+});
+
+ +

These stat objects are instances of fs.Stat.

+ +

fs.unwatchFile(filename)

+ +

Stop watching for changes on filename.

+ +

fs.Stats

+ +

Objects returned from fs.stat() and fs.lstat() are of this type.

+ +
    +
  • stats.isFile()
  • +
  • stats.isDirectory()
  • +
  • stats.isBlockDevice()
  • +
  • stats.isCharacterDevice()
  • +
  • stats.isSymbolicLink() (only valid with fs.lstat())
  • +
  • stats.isFIFO()
  • +
  • stats.isSocket()
  • +
+ + +

fs.ReadStream

+ +

ReadStream is a readable stream.

+ +

fs.createReadStream(path, [options])

+ +

Returns a new ReadStream object.

+ +

options is an object with the following defaults:

+ +
{ 'flags': 'r'
+, 'encoding': 'binary'
+, 'mode': 0666
+, 'bufferSize': 4 * 1024
+}
+
+ +

readStream.readable

+ +

A boolean that is true by default, but turns false after an 'error' +occured, the stream came to an 'end', or destroy() was called.

+ +

readStream.pause()

+ +

Stops the stream from reading further data. No 'data' event will be fired +until the stream is resumed.

+ +

readStream.resume()

+ +

Resumes the stream. Together with pause() this useful to throttle reading.

+ +

readStream.destroy()

+ +

Allows to close the stream before the 'end' is reached. No more events other +than 'close' will be fired after this method has been called.

+ +

fs.WriteStream

+ +

WriteStream is a writable stream.

+ +

fs.createWriteStream(path, [options])

+ +

Returns a new WriteStream object. +options is an object with the following defaults:

+ +
{ 'flags': 'w'
+, 'encoding': 'binary'
+, 'mode': 0666
+}
+
+ +

writeStream.writeable

+ +

A boolean that is true by default, but turns false after an 'error' +occurred or end() / destroy() was called.

+ +

writeStream.write(data, encoding='utf8')

+ +

Returns true if the data was flushed to the kernel, and false if it was +queued up for being written later. A 'drain' will fire after all queued data +has been written.

+ +

The second optional parameter specifies the encoding of for the string.

+ +

writeStream.end()

+ +

Closes the stream right after all queued write() calls have finished.

+ +

writeStream.destroy()

+ +

Allows to close the stream regardless of its current state.

+ +

HTTP

+ +

To use the HTTP server and client one must require('http').

+ +

The HTTP interfaces in Node are designed to support many features +of the protocol which have been traditionally difficult to use. +In particular, large, possibly chunk-encoded, messages. The interface is +careful to never buffer entire requests or responses--the +user is able to stream data.

+ +

HTTP message headers are represented by an object like this:

+ +
{ 'content-length': '123'
+, 'content-type': 'text/plain'
+, 'stream': 'keep-alive'
+, 'accept': '*/*'
+}
+
+ +

Keys are lowercased. Values are not modified.

+ +

In order to support the full spectrum of possible HTTP applications, Node's +HTTP API is very low-level. It deals with stream handling and message +parsing only. It parses a message into headers and body but it does not +parse the actual headers or the body.

+ +

HTTPS is supported if OpenSSL is available on the underlying platform.

+ +

http.Server

+ +

This is an EventEmitter with the following events:

+ +

Event: 'request'

+ +

function (request, response) { }

+ +

request is an instance of http.ServerRequest and response is + an instance of http.ServerResponse

+ +

Event: 'connection'

+ +

function (stream) { }

+ +

When a new TCP stream is established. stream is an object of type + net.Stream. Usually users will not want to access this event. The + stream can also be accessed at request.connection.

+ +

Event: 'close'

+ +

function (errno) { }

+ +

Emitted when the server closes.

+ +

http.createServer(requestListener, [options])

+ +

Returns a new web server object.

+ +

The options argument is optional. The +options argument accepts the same values as the +options argument for net.Server.

+ +

The requestListener is a function which is automatically +added to the 'request' event.

+ +

Event: 'request'

+ +

function (request, response) {}

+ +

Emitted each time there is request. Note that there may be multiple requests +per connection (in the case of keep-alive connections).

+ +

Event: 'upgrade'

+ +

function (request, socket, head)

+ +

Emitted each time a client requests a http upgrade. If this event isn't +listened for, then clients requesting an upgrade will have their connections +closed.

+ +
    +
  • request is the arguments for the http request, as it is in the request event.
  • +
  • socket is the network socket between the server and client.
  • +
  • head is an instance of Buffer, the first packet of the upgraded stream, this may be empty.
  • +
+ + +

After this event is emitted, the request's socket will not have a data +event listener, meaning you will need to bind to it in order to handle data +sent to the server on that socket.

+ +

Event: 'clientError'

+ +

function (exception) {}

+ +

If a client connection emits an 'error' event - it will forwarded here.

+ +

server.listen(port, hostname=null, callback=null)

+ +

Begin accepting connections on the specified port and hostname. If the +hostname is omitted, the server will accept connections directed to any +IPv4 address (INADDR_ANY).

+ +

To listen to a unix socket, supply a filename instead of port and hostname.

+ +

This function is asynchronous. The last parameter callback will be called +when the server has been bound to the port.

+ +

server.listen(path, callback=null)

+ +

Start a UNIX socket server listening for connections on the given path.

+ +

This function is asynchronous. The last parameter callback will be called +when the server has been bound.

+ +

server.setSecure(credentials)

+ +

Enables HTTPS support for the server, with the crypto module credentials specifying the private key and certificate of the server, and optionally the CA certificates for use in client authentication.

+ +

If the credentials hold one or more CA certificates, then the server will request for the client to submit a client certificate as part of the HTTPS connection handshake. The validity and content of this can be accessed via verifyPeer() and getPeerCertificate() from the server's request.connection.

+ +

server.close()

+ +

Stops the server from accepting new connections.

+ +

http.ServerRequest

+ +

This object is created internally by a HTTP server--not by +the user--and passed as the first argument to a 'request' listener.

+ +

This is an EventEmitter with the following events:

+ +

Event: 'data'

+ +

function (chunk) { }

+ +

Emitted when a piece of the message body is received.

+ +

Example: A chunk of the body is given as the single +argument. The transfer-encoding has been decoded. The +body chunk is a string. The body encoding is set with +request.setBodyEncoding().

+ +

Event: 'end'

+ +

function () { }

+ +

Emitted exactly once for each message. No arguments. After +emitted no other events will be emitted on the request.

+ +

request.method

+ +

The request method as a string. Read only. Example: +'GET', 'DELETE'.

+ +

request.url

+ +

Request URL string. This contains only the URL that is +present in the actual HTTP request. If the request is:

+ +
GET /status?name=ryan HTTP/1.1\r\n
+Accept: text/plain\r\n
+\r\n
+
+ +

Then request.url will be:

+ +
'/status?name=ryan'
+
+ +

If you would like to parse the URL into its parts, you can use +require('url').parse(request.url). Example:

+ +
node> require('url').parse('/status?name=ryan')
+{ href: '/status?name=ryan'
+, search: '?name=ryan'
+, query: 'name=ryan'
+, pathname: '/status'
+}
+
+ +

If you would like to extract the params from the query string, +you can use the require('querystring').parse function, or pass +true as the second argument to require('url').parse. Example:

+ +
node> require('url').parse('/status?name=ryan', true)
+{ href: '/status?name=ryan'
+, search: '?name=ryan'
+, query: { name: 'ryan' }
+, pathname: '/status'
+}
+
+ +

request.headers

+ +

Read only.

+ +

request.httpVersion

+ +

The HTTP protocol version as a string. Read only. Examples: +'1.1', '1.0'. +Also request.httpVersionMajor is the first integer and +request.httpVersionMinor is the second.

+ +

request.setEncoding(encoding='binary')

+ +

Set the encoding for the request body. Either 'utf8' or 'binary'. Defaults +to 'binary'.

+ +

request.pause()

+ +

Pauses request from emitting events. Useful to throttle back an upload.

+ +

request.resume()

+ +

Resumes a paused request.

+ +

request.connection

+ +

The net.Stream object assocated with the connection.

+ +

With HTTPS support, use request.connection.verifyPeer() and +request.connection.getPeerCertificate() to obtain the client's +authentication details.

+ +

http.ServerResponse

+ +

This object is created internally by a HTTP server--not by the user. It is +passed as the second parameter to the 'request' event. It is a writable stream.

+ +

response.writeHead(statusCode[, reasonPhrase] , headers)

+ +

Sends a response header to the request. The status code is a 3-digit HTTP +status code, like 404. The last argument, headers, are the response headers. +Optionally one can give a human-readable reasonPhrase as the second +argument.

+ +

Example:

+ +
var body = 'hello world';
+response.writeHead(200, {
+  'Content-Length': body.length,
+  'Content-Type': 'text/plain'
+});
+
+ +

This method must only be called once on a message and it must +be called before response.end() is called.

+ +

response.write(chunk, encoding)

+ +

This method must be called after writeHead was +called. It sends a chunk of the response body. This method may +be called multiple times to provide successive parts of the body.

+ +

If chunk is a string, the second parameter +specifies how to encode it into a byte stream. By default the +encoding is 'ascii'.

+ +

Note: This is the raw HTTP body and has nothing to do with +higher-level multi-part body encodings that may be used.

+ +

The first time response.write() is called, it will send the buffered +header information and the first body to the client. The second time +response.write() is called, Node assumes you're going to be streaming +data, and sends that separately. That is, the response is buffered up to the +first chunk of body.

+ +

response.end()

+ +

This method signals to the server that all of the response headers and body +has been sent; that server should consider this message complete. +The method, response.end(), MUST be called on each +response.

+ +

http.Client

+ +

An HTTP client is constructed with a server address as its +argument, the returned handle is then used to issue one or more +requests. Depending on the server connected to, the client might +pipeline the requests or reestablish the stream after each +stream. Currently the implementation does not pipeline requests.

+ +

Example of connecting to google.com:

+ +
var sys = require('sys'),
+   http = require('http');
+var google = http.createClient(80, 'www.google.com');
+var request = google.request('GET', '/',
+  {'host': 'www.google.com'});
+request.end();
+request.addListener('response', function (response) {
+  sys.puts('STATUS: ' + response.statusCode);
+  sys.puts('HEADERS: ' + JSON.stringify(response.headers));
+  response.setEncoding('utf8');
+  response.addListener('data', function (chunk) {
+    sys.puts('BODY: ' + chunk);
+  });
+});
+
+ +

http.createClient(port, host, secure, credentials)

+ +

Constructs a new HTTP client. port and +host refer to the server to be connected to. A +stream is not established until a request is issued.

+ +

secure is an optional boolean flag to enable https support and credentials is an optional credentials object from the crypto module, which may hold the client's private key, certificate, and a list of trusted CA certificates.

+ +

If the connection is secure, but no explicit CA certificates are passed in the credentials, then node.js will default to the publicly trusted list of CA certificates, as given in http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt

+ +

client.request([method], path, [request_headers])

+ +

Issues a request; if necessary establishes stream. Returns a http.ClientRequest instance.

+ +

method is optional and defaults to 'GET' if omitted.

+ +

request_headers is optional. +Additional request headers might be added internally +by Node. Returns a ClientRequest object.

+ +

Do remember to include the Content-Length header if you +plan on sending a body. If you plan on streaming the body, perhaps +set Transfer-Encoding: chunked.

+ +

NOTE: the request is not complete. This method only sends the header of +the request. One needs to call request.end() to finalize the request and +retrieve the response. (This sounds convoluted but it provides a chance for +the user to stream a body to the server with request.write().)

+ +

client.verifyPeer()

+ +

Returns true or false depending on the validity of the server's certificate in the context of the defined or default list of trusted CA certificates.

+ +

client.getPeerCertificate()

+ +

Returns a JSON structure detailing the server's certificate, containing a dictionary with keys for the certificate 'subject', 'issuer', 'valid_from' and 'valid_to'

+ +

http.ClientRequest

+ +

This object is created internally and returned from the request() method +of a http.Client. It represents an in-progress request whose header has +already been sent.

+ +

To get the response, add a listener for 'response' to the request object. +'response' will be emitted from the request object when the response +headers have been received. The 'response' event is executed with one +argument which is an instance of http.ClientResponse.

+ +

During the 'response' event, one can add listeners to the +response object; particularly to listen for the 'data' event. Note that +the 'response' event is called before any part of the response body is received, +so there is no need to worry about racing to catch the first part of the +body. As long as a listener for 'data' is added during the 'response' +event, the entire body will be caught.

+ +
// Good
+request.addListener('response', function (response) {
+  response.addListener('data', function (chunk) {
+    sys.puts('BODY: ' + chunk);
+  });
+});
+
+// Bad - misses all or part of the body
+request.addListener('response', function (response) {
+  setTimeout(function () {
+    response.addListener('data', function (chunk) {
+      sys.puts('BODY: ' + chunk);
+    });
+  }, 10);
+});
+
+ +

This is a writable stream.

+ +

This is an EventEmitter with the following events:

+ +

Event 'response'

+ +

function (response) { }

+ +

Emitted when a response is received to this request. This event is emitted only once. The +response argument will be an instance of http.ClientResponse.

+ +

request.write(chunk, encoding='ascii')

+ +

Sends a chunk of the body. By calling this method +many times, the user can stream a request body to a +server--in that case it is suggested to use the +['Transfer-Encoding', 'chunked'] header line when +creating the request.

+ +

The chunk argument should be an array of integers +or a string.

+ +

The encoding argument is optional and only +applies when chunk is a string. The encoding +argument should be either 'utf8' or +'ascii'. By default the body uses ASCII encoding, +as it is faster.

+ +

request.end()

+ +

Finishes sending the request. If any parts of the body are +unsent, it will flush them to the stream. If the request is +chunked, this will send the terminating '0\r\n\r\n'.

+ +

http.ClientResponse

+ +

This object is created when making a request with http.Client. It is +passed to the 'response' event of the request object.

+ +

The response implements the readable stream interface.

+ +

Event: 'data'

+ +

function (chunk) {}

+ +

Emitted when a piece of the message body is received.

+ +
Example: A chunk of the body is given as the single
+argument. The transfer-encoding has been decoded.  The
+body chunk a String.  The body encoding is set with
+`response.setBodyEncoding()`.
+
+ +

Event: 'end'

+ +

function () {}

+ +

Emitted exactly once for each message. No arguments. After +emitted no other events will be emitted on the response.

+ +

response.statusCode

+ +

The 3-digit HTTP response status code. E.G. 404.

+ +

response.httpVersion

+ +

The HTTP version of the connected-to server. Probably either +'1.1' or '1.0'. +Also response.httpVersionMajor is the first integer and +response.httpVersionMinor is the second.

+ +

response.headers

+ +

The response headers.

+ +

response.setEncoding(encoding)

+ +

Set the encoding for the response body. Either 'utf8' or 'binary'. +Defaults to 'binary'.

+ +

response.pause()

+ +

Pauses response from emitting events. Useful to throttle back a download.

+ +

response.resume()

+ +

Resumes a paused response.

+ +

response.client

+ +

A reference to the http.Client that this response belongs to.

+ +

net.Server

+ +

This class is used to create a TCP or UNIX server.

+ +

Here is an example of a echo server which listens for connections +on port 8124:

+ +
var net = require('net');
+var server = net.createServer(function (stream) {
+  stream.setEncoding('utf8');
+  stream.addListener('connect', function () {
+    stream.write('hello\r\n');
+  });
+  stream.addListener('data', function (data) {
+    stream.write(data);
+  });
+  stream.addListener('end', function () {
+    stream.write('goodbye\r\n');
+    stream.end();
+  });
+});
+server.listen(8124, 'localhost');
+
+ +

To listen on the socket '/tmp/echo.sock', the last line would just be +changed to

+ +
server.listen('/tmp/echo.sock');
+
+ +

This is an EventEmitter with the following events:

+ +

Event: 'connection'

+ +

function (stream) {}

+ +

Emitted when a new connection is made. stream is an instance of +net.Stream.

+ +

Event: 'close'

+ +

function () {}

+ +

Emitted when the server closes.

+ +

net.createServer(connectionListener)

+ +

Creates a new TCP server. The connection_listener argument is +automatically set as a listener for the 'connection' event.

+ +

server.listen(port, host=null, callback=null)

+ +

Begin accepting connections on the specified port and host. If the +host is omitted, the server will accept connections directed to any +IPv4 address (INADDR_ANY).

+ +

This function is asynchronous. The last parameter callback will be called +when the server has been bound.

+ +

server.listen(path, callback=null)

+ +

Start a UNIX socket server listening for connections on the given path.

+ +

This function is asynchronous. The last parameter callback will be called +when the server has been bound.

+ +

server.close()

+ +

Stops the server from accepting new connections. This function is +asynchronous, the server is finally closed when the server emits a 'close' +event.

+ +

net.Stream

+ +

This object is an abstraction of of a TCP or UNIX socket. net.Stream +instance implement a duplex stream interface. They can be created by the +user and used as a client (with connect()) or they can be created by Node +and passed to the user through the 'connection' event of a server.

+ +

net.Stream instances are an EventEmitters with the following events:

+ +

Event: 'connect'

+ +

function () { }

+ +

Emitted when a stream connection successfully is established. +See connect().

+ +

Event: 'secure'

+ +

function () { }

+ +

Emitted when a stream connection successfully establishes a HTTPS handshake with its peer.

+ +

Event: 'data'

+ +

function (data) { }

+ +

Emitted when data is received. The argument data will be a Buffer or +String. Encoding of data is set by stream.setEncoding(). +(See the section on Readable Streams for more infromation.)

+ +

Event: 'end'

+ +

function () { }

+ +

Emitted when the other end of the stream sends a FIN packet. After this is +emitted the readyState will be 'writeOnly'. One should probably just +call stream.end() when this event is emitted.

+ +

Event: 'timeout'

+ +

function () { }

+ +

Emitted if the stream times out from inactivity. This is only to notify that +the stream has been idle. The user must manually close the connection.

+ +

See also: stream.setTimeout()

+ +

Event: 'drain'

+ +

function () { }

+ +

Emitted when the write buffer becomes empty. Can be used to throttle uploads.

+ +

Event: 'error'

+ +

function (exception) { }

+ +

Emitted when an error occurs. The 'close' event will be called directly +following this event.

+ +

Event: 'close'

+ +

function () { }

+ +

Emitted once the stream is fully closed. The argument had_error is a boolean which says if +the stream was closed due to a transmission +error.

+ +

net.createConnection(port, host='127.0.0.1')

+ +

Construct a new stream object and opens a stream to the specified port +and host. If the second parameter is omitted, localhost is assumed.

+ +

When the stream is established the 'connect' event will be emitted.

+ +

stream.connect(port, host='127.0.0.1')

+ +

Opens a stream to the specified port and host. createConnection() +also opens a stream; normally this method is not needed. Use this only if +a stream is closed and you want to reuse the object to connect to another +server.

+ +

This function is asynchronous. When the 'connect' event is emitted the +stream is established. If there is a problem connecting, the 'connect' +event will not be emitted, the 'error' event will be emitted with +the exception.

+ +

stream.remoteAddress

+ +

The string representation of the remote IP address. For example, +'74.125.127.100' or '2001:4860:a005::68'.

+ +

This member is only present in server-side connections.

+ +

stream.readyState

+ +

Either 'closed', 'open', 'opening', 'readOnly', or 'writeOnly'.

+ +

stream.setEncoding(encoding)

+ +

Sets the encoding (either 'ascii', 'utf8', or 'binary') for data that is +received.

+ +

stream.setSecure(credentials)

+ +

Enables HTTPS support for the stream, with the crypto module credentials specifying the private key and certificate of the stream, and optionally the CA certificates for use in peer authentication.

+ +

If the credentials hold one ore more CA certificates, then the stream will request for the peer to submit a client certificate as part of the HTTPS connection handshake. The validity and content of this can be accessed via verifyPeer() and getPeerCertificate().

+ +

stream.verifyPeer()

+ +

Returns true or false depending on the validity of the peers's certificate in the context of the defined or default list of trusted CA certificates.

+ +

stream.getPeerCertificate()

+ +

Returns a JSON structure detailing the peer's certificate, containing a dictionary with keys for the certificate 'subject', 'issuer', 'valid_from' and 'valid_to'

+ +

stream.write(data, encoding='ascii')

+ +

Sends data on the stream. The second parameter specifies the encoding in +the case of a string--it defaults to ASCII because encoding to UTF8 is rather +slow.

+ +

Returns true if the entire data was flushed successfully to the kernel +buffer. Returns false if all or part of the data was queued in user memory. +'drain' will be emitted when the buffer is again free.

+ +

stream.end()

+ +

Half-closes the stream. I.E., it sends a FIN packet. It is possible the +server will still send some data. After calling this readyState will be +'readOnly'.

+ +

stream.destroy()

+ +

Ensures that no more I/O activity happens on this stream. Only necessary in +case of errors (parse error or so).

+ +

stream.pause()

+ +

Pauses the reading of data. That is, 'data' events will not be emitted. +Useful to throttle back an upload.

+ +

stream.resume()

+ +

Resumes reading after a call to pause().

+ +

stream.setTimeout(timeout)

+ +

Sets the stream to timeout after timeout milliseconds of inactivity on +the stream. By default net.Stream do not have a timeout.

+ +

When an idle timeout is triggered the stream will receive a 'timeout' +event but the connection will not be severed. The user must manually end() +or destroy() the stream.

+ +

If timeout is 0, then the existing idle timeout is disabled.

+ +

stream.setNoDelay(noDelay=true)

+ +

Disables the Nagle algorithm. By default TCP connections use the Nagle +algorithm, they buffer data before sending it off. Setting noDelay will +immediately fire off data each time stream.write() is called.

+ +

stream.setKeepAlive(enable=false, initialDelay)

+ +

Enable/disable keep-alive functionality, and optionally set the initial +delay before the first keepalive probe is sent on an idle stream. +Set initialDelay (in milliseconds) to set the delay between the last +data packet received and the first keepalive probe. Setting 0 for +initialDelay will leave the value unchanged from the default +(or previous) setting.

+ +

Crypto

+ +

Use require('crypto') to access this module.

+ +

The crypto module requires OpenSSL to be available on the underlying platform. It offers a way of encapsulating secure credentials to be used as part of a secure HTTPS net or http connection.

+ +

It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods.

+ +

crypto.createCredentials(details)

+ +

Creates a credentials object, with the optional details being a dictionary with keys:

+ +

key : a string holding the PEM encoded private key

+ +

cert : a string holding the PEM encoded certificate

+ +

ca : either a string or list of strings of PEM encoded CA certificates to trust.

+ +

If no 'ca' details are given, then node.js will use the default publicly trusted list of CAs as given in +http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt

+ +

crypto.createHash(algorithm)

+ +

Creates and returns a hash object, a cryptographic hash with the given algorithm which can be used to generate hash digests.

+ +

algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are sha1, md5, sha256, sha512, etc. On recent releases, openssl list-message-digest-algorithms will display the available digest algorithms.

+ +

hash.update(data)

+ +

Updates the hash content with the given data. This can be called many times with new data as it is streamed.

+ +

hash.digest(encoding)

+ +

Calculates the digest of all of the passed data to be hashed. The encoding can be 'hex', 'binary' or 'base64'.

+ +

crypto.createHmac(algorithm, key)

+ +

Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key.

+ +

algorithm is dependent on the available algorithms supported by OpenSSL - see createHash above. +key is the hmac key to be used.

+ +

hmac.update(data)

+ +

Update the hmac content with the given data. This can be called many times with new data as it is streamed.

+ +

hmac.digest(encoding)

+ +

Calculates the digest of all of the passed data to the hmac. The encoding can be 'hex', 'binary' or 'base64'.

+ +

crypto.createCipher(algorithm, key)

+ +

Creates and returns a cipher object, with the given algorithm and key.

+ +

algorithm is dependent on OpenSSL, examples are aes192, etc. On recent releases, openssl list-cipher-algorithms will display the available cipher algorithms.

+ +

cipher.update(data, input_encoding, output_encoding)

+ +

Updates the cipher with data, the encoding of which is given in input_encoding and can be 'utf8', 'ascii' or 'binary'. The output_encoding specifies the output format of the enciphered data, and can be 'binary', 'base64' or 'hex'.

+ +

Returns the enciphered contents, and can be called many times with new data as it is streamed.

+ +

cipher.final(output_encoding)

+ +

Returns any remaining enciphered contents, with output_encoding as update above.

+ +

crypto.createDecipher(algorithm, key)

+ +

Creates and returns a decipher object, with the given algorithm and key. This is the mirror of the cipher object above.

+ +

decipher.update(data, input_encoding, output_encoding)

+ +

Updates the decipher with data, which is encoded in 'binary', 'base64' or 'hex'. The output_decoding specifies in what format to return the deciphered plaintext - either 'binary', 'ascii' or 'utf8'.

+ +

decipher.final(output_encoding)

+ +

Returns any remaining plaintext which is deciphered, with `output_encoding' as update above.

+ +

crypto.createSign(algorithm)

+ +

Creates and returns a signing object, with the given algorithm. On recent OpenSSL releases, openssl list-public-key-algorithms will display the available signing algorithms. Examples are 'RSA-SHA256'.

+ +

signer.update(data)

+ +

Updates the signer object with data. This can be called many times with new data as it is streamed.

+ +

signer.sign(private_key, output_format)

+ +

Calculates the signature on all the updated data passed through the signer. private_key is a string containing the PEM encoded private key for signing.

+ +

Returns the signature in output_format which can be 'binary', 'hex' or 'base64'

+ +

crypto.createVerify(algorithm)

+ +

Creates and returns a verification object, with the given algorithm. This is the mirror of the signing object above.

+ +

verifier.update(data)

+ +

Updates the verifyer object with data. This can be called many times with new data as it is streamed.

+ +

verifier.verify(public_key, signature, signature_format)

+ +

Verifies the signed data by using the public_key which is a string containing the PEM encoded public key, and signature, which is the previously calculates signature for the data, in the signature_format which can be 'binary', 'hex' or 'base64'.

+ +

Returns true or false depending on the validity of the signature for the data and public key.

+ +

DNS

+ +

Use require('dns') to access this module.

+ +

Here is an example which resolves 'www.google.com' then reverse +resolves the IP addresses which are returned.

+ +
var dns = require('dns'),
+    sys = require('sys');
+
+dns.resolve4('www.google.com', function (err, addresses) {
+  if (err) throw err;
+
+  sys.puts('addresses: ' + JSON.stringify(addresses));
+
+  for (var i = 0; i < addresses.length; i++) {
+    var a = addresses[i];
+    dns.reverse(a, function (err, domains) {
+      if (err) {
+        sys.puts('reverse for ' + a + ' failed: ' + 
+          err.message);
+      } else {
+        sys.puts('reverse for ' + a + ': ' + 
+          JSON.stringify(domains));
+      }
+    });
+  }
+});
+
+ +

dns.resolve(domain, rrtype = 'A', callback)

+ +

Resolves a domain (e.g. 'google.com') into an array of the record types +specified by rrtype. Valid rrtypes are A (IPV4 addresses), AAAA (IPV6 +addresses), MX (mail exchange records), TXT (text records), SRV (SRV +records), and PTR (used for reverse IP lookups).

+ +

The callback has arguments (err, addresses). The type of each item +in addresses is determined by the record type, and described in the +documentation for the corresponding lookup methods below.

+ +

On error, err would be an instanceof Error object, where err.errno is +one of the error codes listed below and err.message is a string describing +the error in English.

+ +

dns.resolve4(domain, callback)

+ +

The same as dns.resolve(), but only for IPv4 queries (A records). +addresses is an array of IPv4 addresses (e.g.
+['74.125.79.104', '74.125.79.105', '74.125.79.106']).

+ +

dns.resolve6(domain, callback)

+ +

The same as dns.resolve4() except for IPv6 queries (an AAAA query).

+ +

dns.resolveMx(domain, callback)

+ +

The same as dns.resolve(), but only for mail exchange queries (MX records).

+ +

addresses is an array of MX records, each with a priority and an exchange +attribute (e.g. [{'priority': 10, 'exchange': 'mx.example.com'},...]).

+ +

dns.resolveTxt(domain, callback)

+ +

The same as dns.resolve(), but only for text queries (TXT records). +addresses is an array of the text records available for domain (e.g., +['v=spf1 ip4:0.0.0.0 ~all']).

+ +

dns.resolveSrv(domain, callback)

+ +

The same as dns.resolve(), but only for service records (SRV records). +addresses is an array of the SRV records available for domain. Properties +of SRV records are priority, weight, port, and name (e.g., +[{'priority': 10, {'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...]).

+ +

dns.reverse(ip, callback)

+ +

Reverse resolves an ip address to an array of domain names.

+ +

The callback has arguments (err, domains).

+ +

If there an an error, err will be non-null and an instanceof the Error +object.

+ +

Each DNS query can return an error code.

+ +
    +
  • dns.TEMPFAIL: timeout, SERVFAIL or similar.
  • +
  • dns.PROTOCOL: got garbled reply.
  • +
  • dns.NXDOMAIN: domain does not exists.
  • +
  • dns.NODATA: domain exists but no data of reqd type.
  • +
  • dns.NOMEM: out of memory while processing.
  • +
  • dns.BADQUERY: the query is malformed.
  • +
+ + +

Assert

+ +

This module is used for writing unit tests for your applications, you can +access it with require('assert').

+ +

assert.fail(actual, expected, message, operator)

+ +

Tests if actual is equal to expected using the operator provided.

+ +

assert.ok(value, message)

+ +

Tests if value is a true value, it is equivalent to assert.equal(true, value, message);

+ +

assert.equal(actual, expected, message)

+ +

Tests shallow, coercive equality with the equal comparison operator ( == ).

+ +

assert.notEqual(actual, expected, message)

+ +

Tests shallow, coercive non-equality with the not equal comparison operator ( != ).

+ +

assert.deepEqual(actual, expected, message)

+ +

Tests for deep equality.

+ +

assert.notDeepEqual(actual, expected, message)

+ +

Tests for any deep inequality.

+ +

assert.strictEqual(actual, expected, message)

+ +

Tests strict equality, as determined by the strict equality operator ( === )

+ +

assert.notStrictEqual(actual, expected, message)

+ +

Tests strict non-equality, as determined by the strict not equal operator ( !== )

+ +

assert.throws(block, error, message)

+ +

Expects block to throw an error.

+ +

assert.doesNotThrow(block, error, message)

+ +

Expects block not to throw an error.

+ +

assert.ifError(value)

+ +

Tests if value is not a false value, throws if it is a true value. Useful when testing the first argument, error in callbacks.

+ +

Path

+ +

This module contains utilities for dealing with file paths. Use +require('path') to use it. It provides the following methods:

+ +

path.join(/ path1, path2, ... /)

+ +

Join all arguments together and resolve the resulting path. Example:

+ +
node> require('path').join(
+...   '/foo', 'bar', 'baz/asdf', 'quux', '..')
+'/foo/bar/baz/asdf'
+
+ +

path.normalizeArray(arr)

+ +

Normalize an array of path parts, taking care of '..' and '.' parts. Example:

+ +
path.normalizeArray(['', 
+  'foo', 'bar', 'baz', 'asdf', 'quux', '..'])
+// returns
+[ '', 'foo', 'bar', 'baz', 'asdf' ]
+
+ +

path.normalize(p)

+ +

Normalize a string path, taking care of '..' and '.' parts. Example:

+ +
path.normalize('/foo/bar/baz/asdf/quux/..')
+// returns
+'/foo/bar/baz/asdf'
+
+ +

path.dirname(p)

+ +

Return the directory name of a path. Similar to the Unix dirname command. Example:

+ +
path.dirname('/foo/bar/baz/asdf/quux')
+// returns
+'/foo/bar/baz/asdf'
+
+ +

path.basename(p, ext)

+ +

Return the last portion of a path. Similar to the Unix basename command. Example:

+ +
path.basename('/foo/bar/baz/asdf/quux.html')
+// returns
+'quux.html'
+
+path.basename('/foo/bar/baz/asdf/quux.html', '.html')
+// returns
+'quux'
+
+ +

path.extname(p)

+ +

Return the extension of the path. Everything after the last '.' in the last portion +of the path. If there is no '.' in the last portion of the path or the only '.' is +the first character, then it returns an empty string. Examples:

+ +
path.extname('index.html')
+// returns 
+'.html'
+
+path.extname('index')
+// returns
+''
+
+ +

path.exists(p, callback)

+ +

Test whether or not the given path exists. Then, call the callback argument with either true or false. Example:

+ +
path.exists('/etc/passwd', function (exists) {
+  sys.debug(exists ? "it's there" : "no passwd!");
+});
+
+ +

URL

+ +

This module has utilities for URL resolution and parsing. +Call require('url') to use it.

+ +

Parsed URL objects have some or all of the following fields, depending on +whether or not they exist in the URL string. Any parts that are not in the URL +string will not be in the parsed object. Examples are shown for the URL

+ +

'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

+ +
    +
  • href

    + +

    The full URL that was originally parsed. Example: +'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • +
  • protocol

    + +

    The request protocol. Example: 'http:'

  • +
  • host

    + +

    The full host portion of the URL, including port and authentication information. Example: +'user:pass@host.com:8080'

  • +
  • auth

    + +

    The authentication information portion of a URL. Example: 'user:pass'

  • +
  • hostname

    + +

    Just the hostname portion of the host. Example: 'host.com'

  • +
  • port

    + +

    The port number portion of the host. Example: '8080'

  • +
  • pathname

    + +

    The path section of the URL, that comes after the host and before the query, including the initial slash if present. Example: '/p/a/t/h'

  • +
  • search

    + +

    The 'query string' portion of the URL, including the leading question mark. Example: '?query=string'

  • +
  • query

    + +

    Either the 'params' portion of the query string, or a querystring-parsed object. Example: +'query=string' or {'query':'string'}

  • +
  • hash

    + +

    The 'fragment' portion of the URL including the pound-sign. Example: '#hash'

  • +
+ + +

The following methods are provided by the URL module:

+ +

url.parse(urlStr, parseQueryString=false)

+ +

Take a URL string, and return an object. Pass true as the second argument to also parse +the query string using the querystring module.

+ +

url.format(urlObj)

+ +

Take a parsed URL object, and return a formatted URL string.

+ +

url.resolve(from, to)

+ +

Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag.

+ +

Query String

+ +

This module provides utilities for dealing with query strings. It provides the following methods:

+ +

querystring.stringify(obj, sep='&', eq='=', munge=true)

+ +

Serialize an object to a query string. Optionally override the default separator and assignment characters. +Example:

+ +
querystring.stringify({foo: 'bar'})
+// returns
+'foo=bar'
+
+querystring.stringify({foo: 'bar', baz: 'bob'}, ';', ':')
+// returns
+'foo:bar;baz:bob'
+
+ +

By default, this function will perform PHP/Rails-style parameter mungeing for arrays and objects used as +values within obj. +Example:

+ +
querystring.stringify({foo: 'bar', foo: 'baz', foo: 'boz'})
+// returns
+'foo[]=bar&foo[]=baz&foo[]=boz'
+
+querystring.stringify({foo: {bar: 'baz'}})
+// returns
+'foo[bar]=baz'
+
+ +

If you wish to disable the array mungeing (e.g. when generating parameters for a Java servlet), you +can set the munge argument to false. +Example:

+ +
querystring.stringify({foo: 'bar', foo: 'baz', foo: 'boz'}, '&', '=', false)
+// returns
+'foo=bar&foo=baz&foo=boz'
+
+ +

Note that when munge is false, parameter names with object values will still be munged.

+ +

querystring.parse(str, sep='&', eq='=')

+ +

Deserialize a query string to an object. Optionally override the default separator and assignment characters.

+ +
querystring.parse('a=b&b=c')
+// returns
+{ 'a': 'b'
+, 'b': 'c'
+}
+
+ +

This function can parse both munged and unmunged query strings (see stringify for details).

+ +

querystring.escape

+ +

The escape function used by querystring.stringify, provided so that it could be overridden if necessary.

+ +

querystring.unescape

+ +

The unescape function used by querystring.parse, provided so that it could be overridden if necessary.

+ +

REPL

+ +

A Read-Eval-Print-Loop (REPL) is available both as a standalone program and easily +includable in other programs. REPL provides a way to interactively run +JavaScript and see the results. It can be used for debugging, testing, or +just trying things out.

+ +

By executing node without any arguments from the command-line you will be +dropped into the REPL. It has simplistic emacs line-editting.

+ +
mjr:~$ node
+Type '.help' for options.
+node> a = [ 1, 2, 3];
+[ 1, 2, 3 ]
+node> a.forEach(function (v) {
+...   sys.puts(v);
+...   });
+1
+2
+3
+
+ +

For advanced line-editors, start node with the environmental variable NODE_NO_READLINE=1. +This will start the REPL in canonical terminal settings which will allow you to use with rlwrap.

+ +

For example, you could add this to your bashrc file:

+ +
alias node="env NODE_NO_READLINE=1 rlwrap node"
+
+ +

repl.start(prompt, stream)

+ +

Starts a REPL with prompt as the prompt and stream for all I/O. prompt +is optional and defaults to node>. stream is optional and defaults to +process.openStdin().

+ +

Multiple REPLs may be started against the same running instance of node. Each +will share the same global object but will have unique I/O.

+ +

Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:

+ +
var sys = require("sys"),
+    net = require("net"),
+    repl = require("repl");
+
+connections = 0;
+
+repl.start("node via stdin> ");
+
+net.createServer(function (socket) {
+  connections += 1;
+  repl.start("node via Unix socket> ", socket);
+}).listen("/tmp/node-repl-sock");
+
+net.createServer(function (socket) {
+  connections += 1;
+  repl.start("node via TCP socket> ", socket);
+}).listen(5001);
+
+ +

Running this program from the command line will start a REPL on stdin. Other +REPL clients may connect through the Unix socket or TCP socket. telnet is useful +for connecting to TCP sockets, and socat can be used to connect to both Unix and +TCP sockets.

+ +

By starting a REPL from a Unix socket-based server instead of stdin, you can +connect to a long-running node process without restarting it.

+ +

REPL Features

+ +

Inside the REPL, Control+D will exit. Multi-line expressions can be input.

+ +

The special variable _ (underscore) contains the result of the last expression.

+ +
node> [ "a", "b", "c" ]
+[ 'a', 'b', 'c' ]
+node> _.length 
+3
+node> _ += 1
+4
+
+ +

The REPL provides access to any variables in the global scope. You can expose a variable +to the REPL explicitly by assigning it to the scope object associated with each +REPLServer. For example:

+ +
// repl_test.js
+var repl = require("repl"),
+    msg = "message";
+
+repl.start().scope.m = msg;
+
+ +

Things in the scope object appear as local within the REPL:

+ +
mjr:~$ node repl_test.js 
+node> m
+'message'
+
+ +

There are a few special REPL commands:

+ +
    +
  • .break - While inputting a multi-line expression, sometimes you get lost or just don't care +about completing it. .break will start over.

  • +
  • .clear - Resets the scope object to an empty object and clears any multi-line expression.

  • +
  • .exit - Close the I/O stream, which will cause the REPL to exit.

  • +
  • .help - Show this list of special commands.

  • +
+ + +

Modules

+ +

Node uses the CommonJS module system.

+ +

Node has a simple module loading system. In Node, files and modules are in +one-to-one correspondence. As an example, foo.js loads the module +circle.js in the same directory.

+ +

The contents of foo.js:

+ +
var circle = require('./circle'),
+    sys = require('sys');
+sys.puts( 'The area of a circle of radius 4 is '
+  + circle.area(4));
+
+ +

The contents of circle.js:

+ +
var PI = 3.14;
+
+exports.area = function (r) {
+  return PI * r * r;
+};
+
+exports.circumference = function (r) {
+  return 2 * PI * r;
+};
+
+ +

The module circle.js has exported the functions area() and +circumference(). To export an object, add to the special exports +object. (Alternatively, one can use this instead of exports.) Variables +local to the module will be private. In this example the variable PI is +private to circle.js. The function puts() comes from the module 'sys', +which is a built-in module. Modules which are not prefixed by './' are +built-in module--more about this later.

+ +

A module prefixed with './' is relative to the file calling require(). +That is, circle.js must be in the same directory as foo.js for +require('./circle') to find it.

+ +

Without the leading './', like require('assert') the module is searched +for in the require.paths array. require.paths on my system looks like +this:

+ +

[ '/home/ryan/.node_libraries' ]

+ +

That is, when require('assert') is called Node looks for:

+ +
    +
  • 1: /home/ryan/.node_libraries/assert.js
  • +
  • 2: /home/ryan/.node_libraries/assert.node
  • +
  • 3: /home/ryan/.node_libraries/assert/index.js
  • +
  • 4: /home/ryan/.node_libraries/assert/index.node
  • +
+ + +

interrupting once a file is found. Files ending in '.node' are binary Addon +Modules; see 'Addons' below. 'index.js' allows one to package a module as +a directory.

+ +

require.paths can be modified at runtime by simply unshifting new +paths onto it, or at startup with the NODE_PATH environmental +variable (which should be a list of paths, colon separated).

+ +

Addons

+ +

Addons are dynamically linked shared objects. They can provide glue to C and +C++ libraries. The API (at the moment) is rather complex, involving +knowledge of several libraries:

+ +
    +
  • V8 JavaScript, a C++ library. Used for interfacing with JavaScript: +creating objects, calling functions, etc. Documented mostly in the +v8.h header file (deps/v8/include/v8.h in the Node source tree).

  • +
  • libev, C event loop library. Anytime one needs to wait for a file +descriptor to become readable, wait for a timer, or wait for a signal to +received one will need to interface with libev. That is, if you perform +any I/O, libev will need to be used. Node uses the EV_DEFAULT event +loop. Documentation can be found http:/cvs.schmorp.de/libev/ev.html[here].

  • +
  • libeio, C thread pool library. Used to execute blocking POSIX system +calls asynchronously. Mostly wrappers already exist for such calls, in +src/file.cc so you will probably not need to use it. If you do need it, +look at the header file deps/libeio/eio.h.

  • +
  • Internal Node libraries. Most importantly is the node::ObjectWrap +class which you will likely want to derive from.

  • +
  • Others. Look in deps/ for what else is available.

  • +
+ + +

Node statically compiles all its dependencies into the executable. When +compiling your module, you don't need to worry about linking to any of these +libraries.

+ +

To get started let's make a small Addon which does the following except in +C++:

+ +
exports.hello = 'world';
+
+ +

To get started we create a file hello.cc:

+ +
#include <v8.h>
+
+using namespace v8;
+
+extern 'C' void
+init (Handle<Object> target) 
+{
+  HandleScope scope;
+  target->Set(String::New("hello"), String::New("World"));
+}
+
+ +

This source code needs to be built into hello.node, the binary Addon. To +do this we create a file called wscript which is python code and looks +like this:

+ +
srcdir = '.'
+blddir = 'build'
+VERSION = '0.0.1'
+
+def set_options(opt):
+  opt.tool_options('compiler_cxx')
+
+def configure(conf):
+  conf.check_tool('compiler_cxx')
+  conf.check_tool('node_addon')
+
+def build(bld):
+  obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
+  obj.target = 'hello'
+  obj.source = 'hello.cc'
+
+ +

Running node-waf configure build will create a file +build/default/hello.node which is our Addon.

+ +

node-waf is just http://code.google.com/p/waf/[WAF], the python-based build system. node-waf is +provided for the ease of users.

+ +

All Node addons must export a function called init with this signature:

+ +
extern 'C' void init (Handle<Object> target)
+
+ +

For the moment, that is all the documentation on addons. Please see +http://github.com/ry/node_postgres for a real example.

+
+
+ + + + + + \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/getelement.html b/node_modules/jsdom/node_modules/htmlparser/testdata/getelement.html new file mode 100644 index 0000000..423d135 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/getelement.html @@ -0,0 +1,3460 @@ + + + + + + + Stack Overflow + + + + + + + + + + + + + + + + +
+ + + + + +
+
+ + +
+ +
+ +
+

Top Questions

+ +
+
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
11
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
10
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
0
+
views
+
+
+ +
+ +
+
+
+
2
+
votes
+
+
+
5
+
answers
+
+
+
88
+
views
+
+
+
+

how to create folder ?

+ +
+ +
+
+ + 20s ago + Luc M 1,261 +
+
+
+ +
+
+
+
4
+
votes
+
+
+
1
+
answer
+
+
+
11
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
2
+
answers
+
+
+
18
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
4
+
views
+
+
+ +
+ +
+
+
+
-2
+
votes
+
+
+
1
+
answer
+
+
+
49
+
views
+
+
+ +
+ +
+
+
+
2
+
votes
+
+
+
4
+
answers
+
+
+
44
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
6
+
views
+
+
+ +
+ +
+
+
+
3
+
votes
+
+
+
3
+
answers
+
+
+
3
+
kviews
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
1
+
view
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
4
+
answers
+
+
+
41
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
1
+
view
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
20
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
3
+
answers
+
+
+
33
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
2
+
answers
+
+
+
18
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
3
+
answers
+
+
+
12
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
10
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
3
+
answers
+
+
+
18
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
9
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
6
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
5
+
views
+
+
+ +
+ +
+
+
+
7
+
votes
+
+
+
9
+
answers
+
+
+
155
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
1
+
view
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
1
+
view
+
+
+
+

Drupal Features include Theme

+ +
+ +
+
+ 2m ago + Linda 93 +
+
+
+ +
+
+
+
3
+
votes
+
+
+
3
+
answers
+
+
+
29
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
8
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
4
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
8
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
4
+
answers
+
+
+
34
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
1
+
view
+
+
+
+

writing hbase reports

+ + +
+ 3m ago + sammy 1 +
+
+
+ +
+
+
+
2
+
votes
+
+
+
2
+
answers
+
+
+
7
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
14
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
1
+
answer
+
+
+
8
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
3
+
answers
+
+
+
23
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
14
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
9
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
14
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
12
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
5
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
14
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
4
+
answers
+
+
+
50
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
6
+
answers
+
+
+
100
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
13
+
answers
+
+
+
133
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
5
+
views
+
+
+ +
+ +
+
+
+
5
+
votes
+
+
+
3
+
answers
+
+
+
24
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
2
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
1
+
answer
+
+
+
14
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
4
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
32
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
4
+
answers
+
+
+
10
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
5
+
views
+
+
+ +
+ +
+
+
+
39
+
votes
+
+
+
16
+
answers
+
+
+
16
+
kviews
+
+
+ +
+ +
+
+
+
3
+
votes
+
+
+
6
+
answers
+
+
+
1
+
kviews
+
+
+ +
+ +
+
+
+
6
+
votes
+
+
+
1
+
answer
+
+
+
72
+
views
+
+
+ +
+ +
+
+
+
2
+
votes
+
+
+
1
+
answer
+
+
+
18
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
4
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
3
+
answers
+
+
+
20
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
2
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
6
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
2
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
17
+
views
+
+
+ +
+ +
+
+
+
-1
+
votes
+
+
+
2
+
answers
+
+
+
13
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
3
+
answers
+
+
+
43
+
views
+
+
+ +
+ +
+
+
+
5
+
votes
+
+
+
5
+
answers
+
+
+
345
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
6
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
3
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
2
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
67
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
3
+
answers
+
+
+
11
+
views
+
+
+ +
+ +
+
+
+
1
+
kvotes
+
+
+
290
+
answers
+
+
+
101
+
kviews
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
2
+
answers
+
+
+
23
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
5
+
views
+
+
+ +
+ +
+
+
+
2
+
votes
+
+
+
2
+
answers
+
+
+
28
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
33
+
views
+
+
+ +
+ +
+
+
+
7
+
votes
+
+
+
5
+
answers
+
+
+
2
+
kviews
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
13
+
views
+
+
+ +
+ +
+
+
+
3
+
votes
+
+
+
4
+
answers
+
+
+
409
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
7
+
views
+
+
+ +
+ +
+
+
+
3
+
votes
+
+
+
4
+
answers
+
+
+
58
+
views
+
+
+ +
+ +
+
+
+
2
+
votes
+
+
+
1
+
answer
+
+
+
10
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
19
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
29
+
views
+
+
+ +
+ +
+
+
+
2
+
votes
+
+
+
1
+
answer
+
+
+
22
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
35
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
6
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
4
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
2
+
answers
+
+
+
33
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
12
+
views
+
+
+ +
+ +
+
+
+
1
+
vote
+
+
+
1
+
answer
+
+
+
12
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
1
+
answer
+
+
+
9
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
4
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
2
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
2
+
answers
+
+
+
32
+
views
+
+
+ +
+ +
+
+
+
0
+
votes
+
+
+
0
+
answers
+
+
+
3
+
views
+
+
+ +
+ +
+ +

Looking for more? Browse the complete list of questions, or popular tags. Help us answer unanswered questions.

+ +
+ + + + + + +
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/jsdom/node_modules/htmlparser/testdata/trackerchecker.html b/node_modules/jsdom/node_modules/htmlparser/testdata/trackerchecker.html new file mode 100644 index 0000000..2dfb1a0 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/testdata/trackerchecker.html @@ -0,0 +1,2733 @@ + + + +www.trackerchecker.com - We check your trackers + + + + + + +
+ + + + + + +
Home || Add a tracker || Latest trackers
+
+ + +
+follow us on Twitter
+Follow trackerchecker on Twitter --> @trackerchecker. +
+
+ + + + + + + +
+We need your input!
We're developing a new version of Trackerchecker and we want to know what functionality the users like to see in Trackerchecker V3! :) Contribute please and tell us what you like to see in Trackerchecker V3! +
Name:
E-mail:
Suggestion
+
+
+ + +
+
+ TrackerList
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 TrackerNameHistoryLastCheckedStatus
1337x.orgview history2010-04-15 18:14:14Open
420project.orgview history2010-04-15 18:23:46Closed
acehd.netview history2010-04-15 18:05:34Closed
acetorrents.netview history2010-04-15 18:09:10Open
adult-cinema-network.netview history2010-04-15 18:21:21Open
all4nothin.netview history2010-04-15 17:35:20Open
allgirltorrents.comview history2010-04-15 17:45:50Closed
allotracker.comview history2010-04-15 17:38:15Open
appz.bitshock.orgview history2010-04-15 17:53:16Open
appzuniverse.orgview history2010-04-15 17:49:10Closed
arabfilms.orgview history2010-04-15 17:36:29Closed
arabseries.orgview history2010-04-15 17:53:15Closed
araditracker.comview history2010-04-15 17:37:17Closed
arena-tr.comview history2010-04-15 18:21:22Closed
arenabg.comview history2010-04-15 17:36:30Closed
artofmisdirection.comview history2010-04-15 17:49:51Closed
asiandvdclub.orgview history2010-04-15 17:35:13Open
at-tracker.orgview history2010-04-15 18:09:40Offline
atomico-torrent.comview history2010-04-15 18:00:09Closed
audionews.ruview history2010-04-15 17:57:00Closed
audiotracer.comview history2010-04-15 18:09:12Closed
audiozonetorrents.comview history2010-04-15 18:22:18Open
avatarbg.infoview history2010-04-15 18:09:40Closed
awesome-hd.comview history2010-04-15 18:03:09Closed
awesome-hd.netview history2010-04-15 18:09:25Closed
baltracker.netview history2010-04-15 18:14:10Open
bestmmatorrents.comview history2010-04-15 18:09:18Closed
bestshare.roview history2010-04-15 17:37:02Closed
bestxvid.orgview history2010-04-15 17:35:13Closed
bit-hdtv.comview history2010-04-15 18:14:09Closed
bitaddict.orgview history2010-04-15 17:45:11Closed
bitchil.comview history2010-04-15 17:45:16Open
bitflamers.comview history2010-04-15 18:21:13Closed
bitgamer.comview history2010-04-15 18:05:52Closed
bithq.orgview history2010-04-15 18:05:56Open
bithumen.ath.cxview history2010-04-15 17:44:41Closed
bitlove.huview history2010-04-15 17:35:02Closed
bitme.orgview history2010-04-15 17:35:16Closed
bitmetv.orgview history2010-04-15 17:40:50Closed
bitmusic.huview history2010-04-15 18:22:56Closed
bitnation.comview history2010-04-15 18:22:18Closed
bitseduce.comview history2010-04-15 17:49:53Closed
bitseek.orgview history2010-04-15 18:21:12Closed
bitseek.orgview history2010-04-15 18:03:09Closed
bitshock.orgview history2010-04-15 17:35:11Closed
bitshock.orgview history2010-04-15 17:56:11Closed
bitsoup.orgview history2010-04-15 17:35:20Closed
bitSpyder.netview history2010-04-15 17:38:08Closed
bittorrents.roview history2010-04-15 17:36:29Closed
bitturk.netview history2010-04-15 18:09:18Closed
biztorrents.comview history2010-04-15 17:45:11Open
blackcats-games.netview history2010-04-15 17:36:28Closed
blades-heaven.comview history2010-04-15 18:24:28Open
blue-bytez.comview history2010-04-15 18:23:03Closed
blue-whitegt.comview history2010-04-15 18:09:29Closed
bmtorrents.netview history2010-04-15 17:38:13Closed
bootytape.comview history2010-04-15 17:45:17Open
bootytorrents.comview history2010-04-15 18:22:21Closed
boxtorrents.comview history2010-04-15 18:22:19Closed
bt.avistaz.comview history2010-04-15 18:14:10Closed
bt.davka.infoview history2010-04-15 17:56:15Open
bt.xbox-sky.ccview history2010-04-15 18:06:25Closed
bt.xbox-sky.comview history2010-04-15 18:21:45Closed
btgigs.infoview history2010-04-15 18:24:22Closed
bwtorrents.comview history2010-04-15 18:05:56Closed
bytelist.orgview history2010-04-15 17:53:12Offline
cartoonchaos.orgview history2010-04-15 17:53:13Closed
ccfbits.orgview history2010-04-15 17:56:59Closed
chdbits.orgview history2010-04-15 18:13:08Open
cheggit.net/view history2010-04-15 17:35:14Open
chilebt.comview history2010-04-15 17:38:18Closed
christiantorrents.comview history2010-04-15 17:56:54Closed
chronictracker.comview history2010-04-15 18:00:23Closed
cinema-obscura.comview history2010-04-15 18:17:13Closed
cinemageddon.orgview history2010-04-15 17:45:11Closed
cinematik.netview history2010-04-15 18:21:20Closed
cleanvobs.orgview history2010-04-15 18:04:32Closed
colombo-bt.orgview history2010-04-15 17:37:16Closed
contego.wsview history2010-04-15 17:45:15Closed
crazytorrent.euview history2010-04-15 18:22:17Closed
czone.roview history2010-04-15 17:49:08Closed
danger.lvview history2010-04-15 18:09:16Closed
definitive-scene.comview history2010-04-15 18:23:46Open
demonoid.comview history2010-04-15 17:45:48Closed
devilwolfs.comview history2010-04-15 18:14:43Open
diablotorrent.huview history2010-04-15 18:04:34Closed
dididave.comview history2010-04-15 17:36:36Closed
digitalhive.orgview history2010-04-15 17:45:10Open
dimeadozen.orgview history2010-04-15 17:40:53Closed
dnbtracker.orgview history2010-04-15 18:17:16Open
docs.torrents.roview history2010-04-15 17:49:53Closed
dvdseed.orgview history2010-04-15 17:56:11Closed
dvdtreasure.euview history2010-04-15 17:53:16Closed
ebookvortex.comview history2010-04-15 17:38:12Open
eclipsetorrents.orgview history2010-04-15 17:40:45Closed
egytorrent.comview history2010-04-15 17:49:09Closed
egytorrent.comview history2010-04-15 18:16:07Open
elbitz.netview history2010-04-15 18:09:35Closed
elektronik.roview history2010-04-15 17:45:16Closed
empornium.usview history2010-04-15 18:10:02Open
eroticsource.plview history2010-04-15 18:06:22Closed
estrenoslatinos.comview history2010-04-15 17:49:09Closed
ethor.netview history2010-04-15 18:09:38Closed
evopt.orgview history2010-04-15 17:49:03Closed
Exigomusicview history2010-04-15 18:17:18Closed
extremebits.orgview history2010-04-15 18:17:19Closed
extremeshare.orgview history2010-04-15 17:36:35Open
faplife.netview history2010-04-15 17:36:44Closed
feedthe.netview history2010-04-15 17:37:23Closed
filebits.orgview history2010-04-15 17:56:52Closed
filelist.orgview history2010-04-15 18:09:17Closed
filelist.roview history2010-04-15 17:49:53Closed
filemp3.orgview history2010-04-15 17:36:43Closed
fileporn.orgview history2010-04-15 17:53:11Closed
flashtorrents.com.arview history2010-04-15 17:56:15Closed
Free The Scene (FTS)view history2010-04-15 18:22:19Closed
Fresh On TV (TvT)view history2010-04-15 18:17:13Open
frztracker.sytes.netview history2010-04-15 18:03:49Closed
fst.omnilounge.co.ukview history2010-04-15 17:36:29Closed
fullcontactzone.comview history2010-04-15 18:03:17Closed
gamecrook.comview history2010-04-15 17:42:03Closed
gbvnet.roview history2010-04-15 17:38:09Closed
gettorrents.orgview history2010-04-15 17:45:03Open
gfxnews.ruview history2010-04-15 17:36:28Open
gigatorrents.wsview history2010-04-15 18:14:10Closed
glabella.orgview history2010-04-15 17:35:12Open
globus-tracker.comview history2010-04-15 17:45:46Closed
goem.orgview history2010-04-15 17:40:51Closed
gormogon.comview history2010-04-15 18:09:29Open
greek-tracker.comview history2010-04-15 17:35:15Closed
grimetorrent.comview history2010-04-15 18:00:31Closed
grtorrent.comview history2010-04-15 18:24:19Closed
guiks.netview history2010-04-15 17:37:19Open
h264torrents.comview history2010-04-15 18:21:54Closed
h33t.comview history2010-04-15 18:17:20Open
hd-bits.roview history2010-04-15 17:37:21Closed
hd-torrents.orgview history2010-04-15 17:56:15Closed
hdbits.orgview history2010-04-15 17:45:47Closed
hdchina.orgview history2010-04-15 18:24:15Closed
hdfrench.comview history2010-04-15 17:53:15Closed
hdme.euview history2010-04-15 18:00:28Closed
hdpre.comview history2010-04-15 17:35:03Closed
hdsource.bizview history2010-04-15 18:04:34Closed
hdstar.orgview history2010-04-15 17:45:12Closed
hdvnbits.orgview history2010-04-15 17:49:50Closed
heaventracker.orgview history2010-04-15 17:36:33Closed
hermeticos.orgview history2010-04-15 18:14:44Closed
horrorcharnel.kicks-ass.orgview history2010-04-15 18:21:15Closed
hungercity.orgview history2010-04-15 17:34:14Open
ifyounotknow.comview history2010-04-15 18:21:19Closed
ilovetorrents.comview history2010-04-15 18:16:08Open
indeep.bizview history2010-04-15 18:17:18Closed
indietorrents.comview history2010-04-15 18:24:30Closed
iplay.roview history2010-04-15 18:09:41Closed
ipodnova.tvview history2010-04-15 17:36:36Closed
iptorrents.comview history2010-04-15 18:23:02Closed
joompalace.comview history2010-04-15 18:24:21Closed
karagarga.netview history2010-04-15 18:09:40Closed
killawaves.netview history2010-04-15 18:06:23Closed
killawaves.orgview history2010-04-15 17:45:13Closed
kinozal.wsview history2010-04-15 18:22:18Open
kludd.comview history2010-04-15 18:00:23Closed
lasttorrents.orgview history2010-04-15 18:09:38Open
leecherslair.comview history2010-04-15 17:49:52Closed
libble.comview history2010-04-15 18:03:18Closed
libitina.netview history2010-04-15 18:21:16Closed
linuxmafia.netview history2010-04-15 17:40:43Offline
linuxtracker.orgview history2010-04-15 17:56:11Closed
lostfilm.tvview history2010-04-15 18:03:20Open
magiciantorrents.comview history2010-04-15 17:49:07Closed
masterstb.comview history2010-04-15 17:34:17Closed
mazetorrents.netview history2010-04-15 17:40:43Offline
medioteka.comview history2010-04-15 17:37:02Closed
mega-bits.comview history2010-04-15 17:34:16Closed
mentol.roview history2010-04-15 17:36:42Closed
metal.iplay.roview history2010-04-15 18:21:21Closed
metalbits.orgview history2010-04-15 17:45:09Closed
midnight-scene.comview history2010-04-15 18:23:43Closed
midnight-torrents.comview history2010-04-15 17:38:14Closed
mma-central.org.ukview history2010-04-15 17:36:27Closed
mma-tracker.netview history2010-04-15 17:38:15Closed
mp3nerds.orgview history2010-04-15 18:22:21Closed
mucis-vid.comview history2010-04-15 17:35:16Closed
musicplace.lvview history2010-04-15 17:53:17Closed
mytorrent.tvview history2010-04-15 17:35:14Closed
norbits.netview history2010-04-15 18:00:21Closed
nordic-t.orgview history2010-04-15 18:00:22Closed
nordicbits.orgview history2010-04-15 18:24:26Closed
novaro.infoview history2010-04-15 18:16:56Closed
novaro.infoview history2010-04-15 18:07:02Closed
noviteti.comview history2010-04-15 18:09:35Closed
ntorrents.netview history2010-04-15 17:34:13Closed
nutorrent.comview history2010-04-15 18:14:45Open
opennetwork.roview history2010-04-15 17:40:42Closed
overtopropetorrents.comview history2010-04-15 17:49:55Closed
ozone-torrents.orgview history2010-04-15 18:00:26Closed
packme.inview history2010-04-15 17:49:54Closed
Pedros btmusicview history2010-04-15 18:17:17Closed
pianosheets.orgview history2010-04-15 18:17:16Closed
pinkytorrents.comview history2010-04-15 18:03:11Open
piranha.excom.usview history2010-04-15 17:40:43Open
Pirate The Net (PtN)view history2010-04-15 17:40:45Closed
piratebits.orgview history2010-04-15 17:44:14Closed
piratefiles.seview history2010-04-15 18:17:11Closed
piratetorrents.nuview history2010-04-15 18:00:28Closed
pisexy.orgview history2010-04-15 17:56:16Closed
polishbytes.netview history2010-04-15 17:57:00Open
polishtracker.orgview history2010-04-15 18:05:34Closed
pornbay.orgview history2010-04-15 18:09:11Open
PotUKview history2010-04-15 17:37:21Closed
powerscene.orgview history2010-04-15 18:14:14Closed
pretome.netview history2010-04-15 17:40:44Closed
proaudiotorrents.orgview history2010-04-15 18:03:17Closed
psytorrents.infoview history2010-04-15 17:49:54Closed
ptfiles.orgview history2010-04-15 18:03:49Closed
punkhc.dyndns.orgview history2010-04-15 17:56:12Closed
puretna.comview history2010-04-15 17:40:53Open
pussytorrents.orgview history2010-04-15 18:05:34Open
rapthe.netview history2010-04-15 18:21:22Closed
rarbg.comview history2010-04-15 18:04:33Open
reload-paradise.netview history2010-04-15 18:05:55Closed
revolutiontt.netview history2010-04-15 18:21:55Closed
rmvbustersview history2010-04-15 18:00:23Open
rmvbusters.plview history2010-04-15 18:03:09Open
scaliwags.orgview history2010-04-15 18:09:42Closed
scene-gold.infoview history2010-04-15 17:37:27Offline
scene-inspired.comview history2010-04-15 18:03:18Open
sceneaccess.orgview history2010-04-15 17:40:44Closed
scenebytes.clview history2010-04-15 17:38:10Closed
scenehd.orgview history2010-04-15 17:45:03Closed
sceneleech.orgview history2010-04-15 17:57:00Closed
SceneLife (ScL)view history2010-04-15 18:23:43Closed
scenetorrents.orgview history2010-04-15 18:23:44Closed
scenetuga.orgview history2010-04-15 18:09:37Closed
sciencehd.netview history2010-04-15 17:53:14Closed
scifitorrents.netview history2010-04-15 17:45:16Offline
secret-cinema.netview history2010-04-15 18:09:44Closed
seductiongr.comview history2010-04-15 18:22:20Closed
seedgames.orgview history2010-04-15 18:10:01Open
seedmore.orgview history2010-04-15 17:49:07Closed
sendthatshit.orgview history2010-04-15 18:23:44Open
sharetorrents.plview history2010-04-15 17:34:13Closed
sharing-torrents.comview history2010-04-15 18:21:18Closed
slosoul.netview history2010-04-15 17:35:19Closed
snowtigers.netview history2010-04-15 17:49:49Closed
softmp3.orgview history2010-04-15 18:14:44Closed
softmupparna.netview history2010-04-15 18:09:11Closed
sounddamage.comview history2010-04-15 18:09:25Closed
spanishtracker.comview history2010-04-15 17:37:27Open
spank-d-monkey.comview history2010-04-15 18:24:23Closed
special.pwtorrents.netview history2010-04-15 18:17:19Closed
speed.cdview history2010-04-15 17:53:17Closed
spiryt.ath.cxview history2010-04-15 17:49:49Closed
sport-scene.netview history2010-04-15 18:17:19Closed
sportbit.orgview history2010-04-15 18:09:09Closed
sportleech.netview history2010-04-15 17:40:48Closed
stmusic.orgview history2010-04-15 18:09:23Open
supertorrents.orgview history2010-04-15 17:57:00Open
swebits.orgview history2010-04-15 17:49:54Closed
sweninjaz.orgview history2010-04-15 18:21:15Closed
swep2p.orgview history2010-04-15 17:37:25Closed
swepiracy.orgview history2010-04-15 18:24:22Closed
swetorrents.no-ip.orgview history2010-04-15 17:35:10Closed
taiphimhd.comview history2010-04-15 17:40:49Open
tastetherainbow.wsview history2010-04-15 17:56:13Closed
teamofgreekz.comview history2010-04-15 18:23:46Closed
tehconnection.euview history2010-04-15 18:06:22Closed
the-zomb.comview history2010-04-15 17:38:13Open
thebox.bzview history2010-04-15 18:09:44Open
thedvdclub.orgview history2010-04-15 17:49:50Open
thegt.netview history2010-04-15 18:00:20Closed
themixingbowl.orgview history2010-04-15 17:38:10Closed
theoccult.bzview history2010-04-15 17:56:12Closed
thepeerhub.comview history2010-04-15 18:24:16Open
theplace.bzview history2010-04-15 18:09:17Closed
thepokerbay.orgview history2010-04-15 17:36:33Open
thevault.bzview history2010-04-15 18:14:45Closed
titaniumtorrents.netview history2010-04-15 17:45:48Offline
tmtorrents.orgview history2010-04-15 18:00:21Closed
topbytes.netview history2010-04-15 17:37:17Closed
topbytes.netview history2010-04-15 18:14:15Closed
tophos.orgview history2010-04-15 18:24:22Closed
torrent-damage.netview history2010-04-15 18:22:22Closed
torrent.itview history2010-04-15 18:24:16Closed
torrent411.comview history2010-04-15 17:45:12Open
torrentbits.roview history2010-04-15 17:37:20Closed
torrentbully.comview history2010-04-15 18:17:15Closed
torrentdownloads.netview history2010-04-15 18:05:55Open
torrentgaming.netview history2010-04-15 18:24:19Closed
torrentgeeks.comview history2010-04-15 18:17:20Offline
torrenthr.orgview history2010-04-15 18:24:16Open
torrentkings.orgview history2010-04-15 17:53:09Closed
torrentleech.orgview history2010-04-15 18:22:46Closed
torrentseed.orgview history2010-04-15 17:35:15Closed
torrentsforall.netview history2010-04-15 17:45:47Open
torrentsmd.comview history2010-04-15 18:00:20Open
torrentvault.orgview history2010-04-15 17:40:51Closed
torrentzilla.orgview history2010-04-15 18:24:11Open
torrentzone.netview history2010-04-15 17:45:04Open
totaltorrents.comview history2010-04-15 17:37:31Closed
trancebits.comview history2010-04-15 18:05:34Closed
trancebooster.netview history2010-04-15 17:56:11Closed
trancetraffic.comview history2010-04-15 17:37:18Closed
tri-tavern.comview history2010-04-15 18:23:19Closed
tribalmixes.comview history2010-04-15 18:20:39Open
tugaleech.comview history2010-04-15 18:24:25Closed
tunebully.comview history2010-04-15 17:49:08Closed
tv.torrents.roview history2010-04-15 17:35:11Closed
tvtorrents.comview history2010-04-15 17:38:02Open
ugstorrents.comview history2010-04-15 18:09:15Closed
uknova.comview history2010-04-15 18:14:15Closed
underground-gamer.comview history2010-04-15 17:49:06Open
victorrent.netview history2010-04-15 17:45:14Closed
vortexnetwork.orgview history2010-04-15 17:53:16Offline
waffles.fmview history2010-04-15 17:53:12Closed
wantedfiles.roview history2010-04-15 17:49:07Open
warezbros.orgview history2010-04-15 18:03:20Closed
what.cdview history2010-04-15 17:53:12Closed
wild-bytes.orgview history2010-04-15 18:00:27Closed
wolfbits.orgview history2010-04-15 18:14:09Closed
worldboxingvideoarchive.comview history2010-04-15 18:09:10Open
www.bt-pt.netview history2010-04-15 18:09:45Closed
www.llywot.comview history2010-04-15 17:53:13Closed
xbitz.orgview history2010-04-15 18:21:21Open
xider.huview history2010-04-15 18:05:34Open
xtremespeeds.netview history2010-04-15 18:04:33Closed
xtremewrestlingtorrents.netview history2010-04-15 18:00:27Open
xtremezone.roview history2010-04-15 18:14:43Closed
yuwabits.netview history2010-04-15 17:45:17Open
zanettetorrent.comview history2010-04-15 18:17:12Closed
zinebytes.orgview history2010-04-15 17:34:18Closed
+
+


+ + +
+ + + + + + diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/01-basic.js b/node_modules/jsdom/node_modules/htmlparser/tests/01-basic.js new file mode 100644 index 0000000..7846898 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/01-basic.js @@ -0,0 +1,61 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Basic test"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = "The TitleHello world"; +exports.expected = + [ { raw: 'html' + , data: 'html' + , type: 'tag' + , name: 'html' + , children: + [ { raw: 'title' + , data: 'title' + , type: 'tag' + , name: 'title' + , children: [ { raw: 'The Title', data: 'The Title', type: 'text' } ] + } + , { raw: 'body' + , data: 'body' + , type: 'tag' + , name: 'body' + , children: + [ { raw: 'Hello world' + , data: 'Hello world' + , type: 'text' + } + ] + } + ] + } + ]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/02-single_tag_1.js b/node_modules/jsdom/node_modules/htmlparser/tests/02-single_tag_1.js new file mode 100644 index 0000000..1735b5e --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/02-single_tag_1.js @@ -0,0 +1,39 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Single Tag 1"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = "
text
"; +exports.expected = + [ { raw: 'br', data: 'br', type: 'tag', name: 'br' } + , { raw: 'text', data: 'text', type: 'text' } + ]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/03-single_tag_2.js b/node_modules/jsdom/node_modules/htmlparser/tests/03-single_tag_2.js new file mode 100644 index 0000000..2e6e92c --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/03-single_tag_2.js @@ -0,0 +1,40 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Single Tag 2"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = "
text
"; +exports.expected = + [ { raw: 'br', data: 'br', type: 'tag', name: 'br' } + , { raw: 'text', data: 'text', type: 'text' } + , { raw: 'br', data: 'br', type: 'tag', name: 'br' } + ]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/04-unescaped_in_script.js b/node_modules/jsdom/node_modules/htmlparser/tests/04-unescaped_in_script.js new file mode 100644 index 0000000..fb2cc3a --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/04-unescaped_in_script.js @@ -0,0 +1,56 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Unescaped chars in script"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = ""; +exports.expected = +[ { raw: 'head' + , data: 'head' + , type: 'tag' + , name: 'head' + , children: + [ { raw: 'script language="Javascript"' + , data: 'script language="Javascript"' + , type: 'script' + , name: 'script' + , attribs: { language: 'Javascript' } + , children: + [ { raw: 'var foo = ""; alert(2 > foo); var baz = 10 << 2; var zip = 10 >> 1; var yap = \"<<>>>><<\";' + , data: 'var foo = ""; alert(2 > foo); var baz = 10 << 2; var zip = 10 >> 1; var yap = \"<<>>>><<\";' + , type: 'text' + } + ] + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/05-tags_in_comment.js b/node_modules/jsdom/node_modules/htmlparser/tests/05-tags_in_comment.js new file mode 100644 index 0000000..68a0779 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/05-tags_in_comment.js @@ -0,0 +1,48 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Special char in comment"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = ""; +exports.expected = +[ { raw: 'head' + , data: 'head' + , type: 'tag' + , name: 'head' + , children: + [ { raw: ' commented out tags Test' + , data: ' commented out tags Test' + , type: 'comment' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/06-comment_in_script.js b/node_modules/jsdom/node_modules/htmlparser/tests/06-comment_in_script.js new file mode 100644 index 0000000..2d04ec0 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/06-comment_in_script.js @@ -0,0 +1,48 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Script source in comment"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = ""; +exports.expected = +[ { raw: 'script' + , data: 'script' + , type: 'script' + , name: 'script' + , children: + [ { raw: 'var foo = 1;' + , data: 'var foo = 1;' + , type: 'comment' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/07-unescaped_in_style.js b/node_modules/jsdom/node_modules/htmlparser/tests/07-unescaped_in_style.js new file mode 100644 index 0000000..563a64a --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/07-unescaped_in_style.js @@ -0,0 +1,49 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Unescaped chars in style"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = ""; +exports.expected = +[ { raw: 'style type="text/css"' + , data: 'style type="text/css"' + , type: 'style' + , name: 'style' + , attribs: { type: 'text/css' } + , children: + [ { raw: '\n body > p\n { font-weight: bold; }' + , data: '\n body > p\n { font-weight: bold; }' + , type: 'text' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/08-extra_spaces_in_tag.js b/node_modules/jsdom/node_modules/htmlparser/tests/08-extra_spaces_in_tag.js new file mode 100644 index 0000000..1767565 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/08-extra_spaces_in_tag.js @@ -0,0 +1,49 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Extra spaces in tag"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = "<\n font \n size='14' \n>the text<\n / \nfont \n>"; +exports.expected = +[ { raw: '\n font \n size=\'14\' \n' + , data: 'font \n size=\'14\'' + , type: 'tag' + , name: 'font' + , attribs: { size: '14' } + , children: + [ { raw: 'the text' + , data: 'the text' + , type: 'text' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/09-unquoted_attrib.js b/node_modules/jsdom/node_modules/htmlparser/tests/09-unquoted_attrib.js new file mode 100644 index 0000000..da6bac7 --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/09-unquoted_attrib.js @@ -0,0 +1,49 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Unquoted attributes"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = "the text"; +exports.expected = +[ { raw: 'font size= 14' + , data: 'font size= 14' + , type: 'tag' + , name: 'font' + , attribs: { size: '14' } + , children: + [ { raw: 'the text' + , data: 'the text' + , type: 'text' + } + ] + } +]; + +})(); diff --git a/node_modules/jsdom/node_modules/htmlparser/tests/10-singular_attribute.js b/node_modules/jsdom/node_modules/htmlparser/tests/10-singular_attribute.js new file mode 100644 index 0000000..6c22e1a --- /dev/null +++ b/node_modules/jsdom/node_modules/htmlparser/tests/10-singular_attribute.js @@ -0,0 +1,43 @@ +(function () { + +function RunningInNode () { + return( + (typeof require) == "function" + && + (typeof exports) == "object" + && + (typeof module) == "object" + && + (typeof __filename) == "string" + && + (typeof __dirname) == "string" + ); +} + +if (!RunningInNode()) { + if (!this.Tautologistics) + this.Tautologistics = {}; + if (!this.Tautologistics.NodeHtmlParser) + this.Tautologistics.NodeHtmlParser = {}; + if (!this.Tautologistics.NodeHtmlParser.Tests) + this.Tautologistics.NodeHtmlParser.Tests = []; + exports = {}; + this.Tautologistics.NodeHtmlParser.Tests.push(exports); +} + +exports.name = "Singular attribute"; +exports.options = { + handler: {} + , parser: {} +}; +exports.html = "