diff --git a/.gitignore b/.gitignore index 678779b26..993e1285a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.swp .DS_Store .project .svn @@ -10,3 +11,4 @@ npm-debug.log /tags /cef/ /sources.gypi +/node/ diff --git a/.gitmodules b/.gitmodules index 5e7fd303a..c7ae0834a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -70,3 +70,9 @@ [submodule "vendor/packages/less.tmbundle"] path = vendor/packages/less.tmbundle url = https://github.com/mathewbyrne/less.tmbundle.git +[submodule "vendor/packages/Mustache.tmbundle"] + path = vendor/packages/Mustache.tmbundle + url = https://github.com/kevinsawicki/Mustache.tmbundle.git +[submodule "vendor/packages/Go.tmbundle"] + path = vendor/packages/Go.tmbundle + url = https://github.com/rsms/Go.tmbundle diff --git a/Rakefile b/Rakefile index 5893ed201..3f3c926eb 100644 --- a/Rakefile +++ b/Rakefile @@ -12,7 +12,7 @@ task :build => "create-xcode-project" do end desc "Create xcode project from gyp file" -task "create-xcode-project" => "update-cef" do +task "create-xcode-project" => ["update-cef", "update-node"] do `rm -rf atom.xcodeproj` `script/generate-sources-gypi` `gyp --depth=. -D CODE_SIGN="#{ENV['CODE_SIGN']}" atom.gyp` @@ -20,15 +20,20 @@ end desc "Update CEF to the latest version specified by the prebuilt-cef submodule" task "update-cef" => "bootstrap" do - exit 1 unless system %{prebuilt-cef/script/download -f cef} + exit 1 unless system %{script/update-cefode} Dir.glob('cef/*.gypi').each do |filename| `sed -i '' -e "s/'include\\//'cef\\/include\\//" -e "s/'libcef_dll\\//'cef\\/libcef_dll\\//" #{filename}` end end +desc "Download node binary" +task "update-node" do + `script/update-node v0.10.1` +end + desc "Download debug symbols for CEF" task "download-cef-symbols" => "update-cef" do - sh %{prebuilt-cef/script/download -s cef} + sh %{script/update-cefode -s} end task "bootstrap" do @@ -80,13 +85,15 @@ task :clean do `rm -rf #{application_path()}` `rm -rf #{BUILD_DIR}` `rm -rf /tmp/atom-compiled-scripts` + `rm -rf node_modules` + `rm -rf cef` end desc "Run the specs" task :test => ["clean", "update-cef", "clone-default-bundles", "build"] do `pkill Atom` if path = application_path() - cmd = "#{path}/Contents/MacOS/Atom --test --resource-path=#{ATOM_SRC_PATH} 2> /dev/null" + cmd = "#{path}/Contents/MacOS/Atom --test --resource-path=#{ATOM_SRC_PATH}" system(cmd) exit($?.exitstatus) else diff --git a/atom.gyp b/atom.gyp index 417fe2de1..12e5a54f3 100644 --- a/atom.gyp +++ b/atom.gyp @@ -22,20 +22,13 @@ '@executable_path/libcef.dylib', '@rpath/Chromium Embedded Framework.framework/Libraries/libcef.dylib', '-change', - '@executable_path/../Frameworks/CocoaOniguruma.framework/Versions/A/CocoaOniguruma', - '@rpath/CocoaOniguruma.framework/Versions/A/CocoaOniguruma', - '-change', '@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle', '@rpath/Sparkle.framework/Versions/A/Sparkle', - '-change', - '@executable_path/libgit2.0.17.0.dylib', - '@rpath/libgit2.framework/Libraries/libgit2.0.17.0.dylib', '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' ], }, 'includes': [ 'cef/cef_paths2.gypi', - 'git2/libgit2.gypi', 'sources.gypi', ], 'target_defaults': { @@ -142,22 +135,22 @@ 'files': [ '<(PRODUCT_DIR)/Atom Helper.app', '<(PRODUCT_DIR)/Atom.framework', - 'native/frameworks/CocoaOniguruma.framework', 'native/frameworks/Sparkle.framework', ], }, - { - 'destination': '<(PRODUCT_DIR)/Atom.app/Contents/Frameworks/libgit2.framework/Libraries', - 'files': [ - 'git2/frameworks/libgit2.0.17.0.dylib', - ], - }, { 'destination': '<(PRODUCT_DIR)/Atom.app/Contents/Frameworks/Chromium Embedded Framework.framework', 'files': [ 'cef/Resources', ], }, + { + # Copy node binary for worker process support. + 'destination': '<(PRODUCT_DIR)/Atom.app/Contents/Resources', + 'files': [ + 'node/node', + ], + }, ], 'postbuilds': [ { @@ -231,7 +224,7 @@ 'INFOPLIST_FILE': 'native/mac/framework-info.plist', 'LD_DYLIB_INSTALL_NAME': '@rpath/Atom.framework/Atom', }, - 'include_dirs': [ '.', 'cef', 'git2' ], + 'include_dirs': [ '.', 'cef' ], 'mac_framework_dirs': [ 'native/frameworks' ], 'sources': [ '<@(includes_common)', @@ -257,24 +250,12 @@ 'native/path_watcher.mm', 'native/v8_extensions/atom.h', 'native/v8_extensions/atom.mm', - 'native/v8_extensions/git.h', - 'native/v8_extensions/git.mm', 'native/v8_extensions/native.h', 'native/v8_extensions/native.mm', - 'native/v8_extensions/onig_reg_exp.h', - 'native/v8_extensions/onig_reg_exp.mm', - 'native/v8_extensions/onig_scanner.h', - 'native/v8_extensions/onig_scanner.mm', - 'native/v8_extensions/readtags.c', - 'native/v8_extensions/readtags.h', - 'native/v8_extensions/tags.h', - 'native/v8_extensions/tags.mm', ], 'link_settings': { 'libraries': [ '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', - 'git2/frameworks/libgit2.0.17.0.dylib', - 'native/frameworks/CocoaOniguruma.framework', 'native/frameworks/Sparkle.framework', ], }, @@ -326,6 +307,7 @@ 'sources': [ '<@(coffee_sources)', '<@(cson_sources)', + '<@(less_sources)' ], 'rules': [ { @@ -360,6 +342,22 @@ '<(compiled_sources_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).json', ], }, + { + 'rule_name': 'less', + 'extension': 'less', + 'inputs': [ + 'script/compile-less', + ], + 'outputs': [ + '<(compiled_sources_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).css', + ], + 'action': [ + 'sh', + 'script/compile-less', + '<(RULE_INPUT_PATH)', + '<(compiled_sources_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).css', + ], + }, ], }, ], diff --git a/benchmark/benchmark-suite.coffee b/benchmark/benchmark-suite.coffee index c0d142a6d..8f549b061 100644 --- a/benchmark/benchmark-suite.coffee +++ b/benchmark/benchmark-suite.coffee @@ -1,5 +1,5 @@ require 'benchmark-helper' -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' _ = require 'underscore' TokenizedBuffer = require 'tokenized-buffer' diff --git a/benchmark/fixtures/medium.coffee b/benchmark/fixtures/medium.coffee index 403353b76..2bdb8c6f7 100644 --- a/benchmark/fixtures/medium.coffee +++ b/benchmark/fixtures/medium.coffee @@ -145,7 +145,7 @@ generate_html = (source, sections) -> # Require our external dependencies, including **Showdown.js** # (the JavaScript implementation of Markdown). -fs = require 'fs' +fs = require 'fs-utils' path = require 'path' showdown = require('./../vendor/showdown').Showdown {spawn, exec} = require 'child_process' diff --git a/git2/frameworks/libgit2.0.17.0.dylib b/git2/frameworks/libgit2.0.17.0.dylib deleted file mode 100755 index 96d777c4d..000000000 Binary files a/git2/frameworks/libgit2.0.17.0.dylib and /dev/null differ diff --git a/git2/include/git2.h b/git2/include/git2.h deleted file mode 100644 index 5f9fc4824..000000000 --- a/git2/include/git2.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#ifndef INCLUDE_git_git_h__ -#define INCLUDE_git_git_h__ - -#include "git2/version.h" - -#include "git2/common.h" -#include "git2/threads.h" -#include "git2/errors.h" - -#include "git2/types.h" - -#include "git2/oid.h" -#include "git2/signature.h" -#include "git2/odb.h" - -#include "git2/repository.h" -#include "git2/revwalk.h" -#include "git2/merge.h" -#include "git2/graph.h" -#include "git2/refs.h" -#include "git2/reflog.h" -#include "git2/revparse.h" - -#include "git2/object.h" -#include "git2/blob.h" -#include "git2/commit.h" -#include "git2/tag.h" -#include "git2/tree.h" -#include "git2/diff.h" - -#include "git2/index.h" -#include "git2/config.h" -#include "git2/transport.h" -#include "git2/remote.h" -#include "git2/clone.h" -#include "git2/checkout.h" -#include "git2/push.h" - -#include "git2/attr.h" -#include "git2/ignore.h" -#include "git2/branch.h" -#include "git2/refspec.h" -#include "git2/net.h" -#include "git2/status.h" -#include "git2/indexer.h" -#include "git2/submodule.h" -#include "git2/notes.h" -#include "git2/reset.h" -#include "git2/message.h" -#include "git2/pack.h" -#include "git2/stash.h" - -#endif diff --git a/git2/include/git2/attr.h b/git2/include/git2/attr.h deleted file mode 100644 index dea44f0e3..000000000 --- a/git2/include/git2/attr.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_attr_h__ -#define INCLUDE_git_attr_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/attr.h - * @brief Git attribute management routines - * @defgroup git_attr Git attribute management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * GIT_ATTR_TRUE checks if an attribute is set on. In core git - * parlance, this the value for "Set" attributes. - * - * For example, if the attribute file contains: - * - * *.c foo - * - * Then for file `xyz.c` looking up attribute "foo" gives a value for - * which `GIT_ATTR_TRUE(value)` is true. - */ -#define GIT_ATTR_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_TRUE_T) - -/** - * GIT_ATTR_FALSE checks if an attribute is set off. In core git - * parlance, this is the value for attributes that are "Unset" (not to - * be confused with values that a "Unspecified"). - * - * For example, if the attribute file contains: - * - * *.h -foo - * - * Then for file `zyx.h` looking up attribute "foo" gives a value for - * which `GIT_ATTR_FALSE(value)` is true. - */ -#define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T) - -/** - * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This - * may be due to the attribute not being mentioned at all or because - * the attribute was explicitly set unspecified via the `!` operator. - * - * For example, if the attribute file contains: - * - * *.c foo - * *.h -foo - * onefile.c !foo - * - * Then for `onefile.c` looking up attribute "foo" yields a value with - * `GIT_ATTR_UNSPECIFIED(value)` of true. Also, looking up "foo" on - * file `onefile.rb` or looking up "bar" on any file will all give - * `GIT_ATTR_UNSPECIFIED(value)` of true. - */ -#define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T) - -/** - * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as - * opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if - * for a file with something like: - * - * *.txt eol=lf - * - * Given this, looking up "eol" for `onefile.txt` will give back the - * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true. - */ -#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T) - -typedef enum { - GIT_ATTR_UNSPECIFIED_T = 0, - GIT_ATTR_TRUE_T, - GIT_ATTR_FALSE_T, - GIT_ATTR_VALUE_T, -} git_attr_t; - -/* - * Return the value type for a given attribute. - * - * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute - * was not set at all), or `VALUE`, if the attribute was set to - * an actual string. - * - * If the attribute has a `VALUE` string, it can be accessed normally - * as a NULL-terminated C string. - * - * @param attr The attribute - * @return the value type for the attribute - */ -GIT_EXTERN(git_attr_t) git_attr_value(const char *attr); - -/** - * Check attribute flags: Reading values from index and working directory. - * - * When checking attributes, it is possible to check attribute files - * in both the working directory (if there is one) and the index (if - * there is one). You can explicitly choose where to check and in - * which order using the following flags. - * - * Core git usually checks the working directory then the index, - * except during a checkout when it checks the index first. It will - * use index only for creating archives or for a bare repo (if an - * index has been specified for the bare repo). - */ -#define GIT_ATTR_CHECK_FILE_THEN_INDEX 0 -#define GIT_ATTR_CHECK_INDEX_THEN_FILE 1 -#define GIT_ATTR_CHECK_INDEX_ONLY 2 - -/** - * Check attribute flags: Using the system attributes file. - * - * Normally, attribute checks include looking in the /etc (or system - * equivalent) directory for a `gitattributes` file. Passing this - * flag will cause attribute checks to ignore that file. - */ -#define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2) - -/** - * Look up the value of one git attribute for path. - * - * @param value_out Output of the value of the attribute. Use the GIT_ATTR_... - * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just - * use the string value for attributes set to a value. You - * should NOT modify or free this value. - * @param repo The repository containing the path. - * @param flags A combination of GIT_ATTR_CHECK... flags. - * @param path The path to check for attributes. Relative paths are - * interpreted relative to the repo root. The file does - * not have to exist, but if it does not, then it will be - * treated as a plain file (not a directory). - * @param name The name of the attribute to look up. - */ -GIT_EXTERN(int) git_attr_get( - const char **value_out, - git_repository *repo, - uint32_t flags, - const char *path, - const char *name); - -/** - * Look up a list of git attributes for path. - * - * Use this if you have a known list of attributes that you want to - * look up in a single call. This is somewhat more efficient than - * calling `git_attr_get()` multiple times. - * - * For example, you might write: - * - * const char *attrs[] = { "crlf", "diff", "foo" }; - * const char **values[3]; - * git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs); - * - * Then you could loop through the 3 values to get the settings for - * the three attributes you asked about. - * - * @param values An array of num_attr entries that will have string - * pointers written into it for the values of the attributes. - * You should not modify or free the values that are written - * into this array (although of course, you should free the - * array itself if you allocated it). - * @param repo The repository containing the path. - * @param flags A combination of GIT_ATTR_CHECK... flags. - * @param path The path inside the repo to check attributes. This - * does not have to exist, but if it does not, then - * it will be treated as a plain file (i.e. not a directory). - * @param num_attr The number of attributes being looked up - * @param names An array of num_attr strings containing attribute names. - */ -GIT_EXTERN(int) git_attr_get_many( - const char **values_out, - git_repository *repo, - uint32_t flags, - const char *path, - size_t num_attr, - const char **names); - -typedef int (*git_attr_foreach_cb)(const char *name, const char *value, void *payload); - -/** - * Loop over all the git attributes for a path. - * - * @param repo The repository containing the path. - * @param flags A combination of GIT_ATTR_CHECK... flags. - * @param path Path inside the repo to check attributes. This does not have - * to exist, but if it does not, then it will be treated as a - * plain file (i.e. not a directory). - * @param callback Function to invoke on each attribute name and value. The - * value may be NULL is the attribute is explicitly set to - * UNSPECIFIED using the '!' sign. Callback will be invoked - * only once per attribute name, even if there are multiple - * rules for a given file. The highest priority rule will be - * used. Return a non-zero value from this to stop looping. - * @param payload Passed on as extra parameter to callback function. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_attr_foreach( - git_repository *repo, - uint32_t flags, - const char *path, - git_attr_foreach_cb callback, - void *payload); - -/** - * Flush the gitattributes cache. - * - * Call this if you have reason to believe that the attributes files on - * disk no longer match the cached contents of memory. This will cause - * the attributes files to be reloaded the next time that an attribute - * access function is called. - */ -GIT_EXTERN(void) git_attr_cache_flush( - git_repository *repo); - -/** - * Add a macro definition. - * - * Macros will automatically be loaded from the top level `.gitattributes` - * file of the repository (plus the build-in "binary" macro). This - * function allows you to add others. For example, to add the default - * macro, you would call: - * - * git_attr_add_macro(repo, "binary", "-diff -crlf"); - */ -GIT_EXTERN(int) git_attr_add_macro( - git_repository *repo, - const char *name, - const char *values); - -/** @} */ -GIT_END_DECL -#endif - diff --git a/git2/include/git2/blob.h b/git2/include/git2/blob.h deleted file mode 100644 index 0c0f3e580..000000000 --- a/git2/include/git2/blob.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_blob_h__ -#define INCLUDE_git_blob_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/blob.h - * @brief Git blob load and write routines - * @defgroup git_blob Git blob load and write routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a blob object from a repository. - * - * @param blob pointer to the looked up blob - * @param repo the repo to use when locating the blob. - * @param id identity of the blob to locate. - * @return 0 or an error code - */ -GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)blob, repo, id, GIT_OBJ_BLOB); -} - -/** - * Lookup a blob object from a repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param blob pointer to the looked up blob - * @param repo the repo to use when locating the blob. - * @param id identity of the blob to locate. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)blob, repo, id, len, GIT_OBJ_BLOB); -} - -/** - * Close an open blob - * - * This is a wrapper around git_object_free() - * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a blob. Failure to do so will cause a memory leak. - * - * @param blob the blob to close - */ - -GIT_INLINE(void) git_blob_free(git_blob *blob) -{ - git_object_free((git_object *) blob); -} - -/** - * Get the id of a blob. - * - * @param blob a previously loaded blob. - * @return SHA1 hash for this blob. - */ -GIT_INLINE(const git_oid *) git_blob_id(const git_blob *blob) -{ - return git_object_id((const git_object *)blob); -} - - -/** - * Get a read-only buffer with the raw content of a blob. - * - * A pointer to the raw content of a blob is returned; - * this pointer is owned internally by the object and shall - * not be free'd. The pointer may be invalidated at a later - * time. - * - * @param blob pointer to the blob - * @return the pointer; NULL if the blob has no contents - */ -GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob); - -/** - * Get the size in bytes of the contents of a blob - * - * @param blob pointer to the blob - * @return size on bytes - */ -GIT_EXTERN(git_off_t) git_blob_rawsize(const git_blob *blob); - -/** - * Read a file from the working folder of a repository - * and write it to the Object Database as a loose blob - * - * @param id return the id of the written blob - * @param repo repository where the blob will be written. - * this repository cannot be bare - * @param relative_path file from which the blob will be created, - * relative to the repository's working dir - * @return 0 or an error code - */ -GIT_EXTERN(int) git_blob_create_fromworkdir(git_oid *id, git_repository *repo, const char *relative_path); - -/** - * Read a file from the filesystem and write its content - * to the Object Database as a loose blob - * - * @param id return the id of the written blob - * @param repo repository where the blob will be written. - * this repository can be bare or not - * @param path file from which the blob will be created - * @return 0 or an error code - */ -GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *id, git_repository *repo, const char *path); - - -typedef int (*git_blob_chunk_cb)(char *content, size_t max_length, void *payload); - -/** - * Write a loose blob to the Object Database from a - * provider of chunks of data. - * - * Provided the `hintpath` parameter is filled, its value - * will help to determine what git filters should be applied - * to the object before it can be placed to the object database. - * - * - * The implementation of the callback has to respect the - * following rules: - * - * - `content` will have to be filled by the consumer. The maximum number - * of bytes that the buffer can accept per call is defined by the - * `max_length` parameter. Allocation and freeing of the buffer will be taken - * care of by the function. - * - * - The callback is expected to return the number of bytes - * that `content` have been filled with. - * - * - When there is no more data to stream, the callback should - * return 0. This will prevent it from being invoked anymore. - * - * - When an error occurs, the callback should return -1. - * - * - * @param id Return the id of the written blob - * - * @param repo repository where the blob will be written. - * This repository can be bare or not. - * - * @param hintpath if not NULL, will help selecting the filters - * to apply onto the content of the blob to be created. - * - * @return GIT_SUCCESS or an error code - */ -GIT_EXTERN(int) git_blob_create_fromchunks( - git_oid *id, - git_repository *repo, - const char *hintpath, - git_blob_chunk_cb callback, - void *payload); - -/** - * Write an in-memory buffer to the ODB as a blob - * - * @param oid return the oid of the written blob - * @param repo repository where to blob will be written - * @param buffer data to be written into the blob - * @param len length of the data - * @return 0 or an error code - */ -GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len); - -/** - * Determine if the blob content is most certainly binary or not. - * - * The heuristic used to guess if a file is binary is taken from core git: - * Searching for NUL bytes and looking for a reasonable ratio of printable - * to non-printable characters among the first 4000 bytes. - * - * @param blob The blob which content should be analyzed - * @return 1 if the content of the blob is detected - * as binary; 0 otherwise. - */ -GIT_EXTERN(int) git_blob_is_binary(git_blob *blob); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/branch.h b/git2/include/git2/branch.h deleted file mode 100644 index 3bda43170..000000000 --- a/git2/include/git2/branch.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_branch_h__ -#define INCLUDE_git_branch_h__ - -#include "common.h" -#include "oid.h" -#include "types.h" - -/** - * @file git2/branch.h - * @brief Git branch parsing routines - * @defgroup git_branch Git branch management - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new branch pointing at a target commit - * - * A new direct reference will be created pointing to - * this target commit. If `force` is true and a reference - * already exists with the given name, it'll be replaced. - * - * The returned reference must be freed by the user. - * - * The branch name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param out Pointer where to store the underlying reference. - * - * @param branch_name Name for the branch; this name is - * validated for consistency. It should also not conflict with - * an already existing branch name. - * - * @param target Object to which this branch should point. This object - * must belong to the given `repo` and can either be a git_commit or a - * git_tag. When a git_tag is being passed, it should be dereferencable - * to a git_commit which oid will be used as the target of the branch. - * - * @param force Overwrite existing branch. - * - * @return 0, GIT_EINVALIDSPEC or an error code. - * A proper reference is written in the refs/heads namespace - * pointing to the provided target commit. - */ -GIT_EXTERN(int) git_branch_create( - git_reference **out, - git_repository *repo, - const char *branch_name, - const git_commit *target, - int force); - -/** - * Delete an existing branch reference. - * - * If the branch is successfully deleted, the passed reference - * object will be freed and invalidated. - * - * @param branch A valid reference representing a branch - * @return 0 on success, or an error code. - */ -GIT_EXTERN(int) git_branch_delete(git_reference *branch); - -/** - * Loop over all the branches and issue a callback for each one. - * - * If the callback returns a non-zero value, this will stop looping. - * - * @param repo Repository where to find the branches. - * - * @param list_flags Filtering flags for the branch - * listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE - * or a combination of the two. - * - * @param branch_cb Callback to invoke per found branch. - * - * @param payload Extra parameter to callback function. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_branch_foreach( - git_repository *repo, - unsigned int list_flags, - int (*branch_cb)( - const char *branch_name, - git_branch_t branch_type, - void *payload), - void *payload -); - -/** - * Move/rename an existing local branch reference. - * - * The new branch name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param branch Current underlying reference of the branch. - * - * @param new_branch_name Target name of the branch once the move - * is performed; this name is validated for consistency. - * - * @param force Overwrite existing branch. - * - * @return 0 on success, GIT_EINVALIDSPEC or an error code. - */ -GIT_EXTERN(int) git_branch_move( - git_reference *branch, - const char *new_branch_name, - int force); - -/** - * Lookup a branch by its name in a repository. - * - * The generated reference must be freed by the user. - * - * The branch name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param out pointer to the looked-up branch reference - * - * @param repo the repository to look up the branch - * - * @param branch_name Name of the branch to be looked-up; - * this name is validated for consistency. - * - * @param branch_type Type of the considered branch. This should - * be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE. - * - * @return 0 on success; GIT_ENOTFOUND when no matching branch - * exists, GIT_EINVALIDSPEC, otherwise an error code. - */ -GIT_EXTERN(int) git_branch_lookup( - git_reference **out, - git_repository *repo, - const char *branch_name, - git_branch_t branch_type); - -/** - * Return the reference supporting the remote tracking branch, - * given a local branch reference. - * - * @param out Pointer where to store the retrieved - * reference. - * - * @param branch Current underlying reference of the branch. - * - * @return 0 on success; GIT_ENOTFOUND when no remote tracking - * reference exists, otherwise an error code. - */ -GIT_EXTERN(int) git_branch_tracking( - git_reference **out, - git_reference *branch); - -/** - * Determine if the current local branch is pointed at by HEAD. - * - * @param branch Current underlying reference of the branch. - * - * @return 1 if HEAD points at the branch, 0 if it isn't, - * error code otherwise. - */ -GIT_EXTERN(int) git_branch_is_head( - git_reference *branch); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/checkout.h b/git2/include/git2/checkout.h deleted file mode 100644 index dfc7e0580..000000000 --- a/git2/include/git2/checkout.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_checkout_h__ -#define INCLUDE_git_checkout_h__ - -#include "common.h" -#include "types.h" -#include "diff.h" - -/** - * @file git2/checkout.h - * @brief Git checkout routines - * @defgroup git_checkout Git checkout routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Checkout behavior flags - * - * In libgit2, checkout is used to update the working directory and index - * to match a target tree. Unlike git checkout, it does not move the HEAD - * commit for you - use `git_repository_set_head` or the like to do that. - * - * Checkout looks at (up to) four things: the "target" tree you want to - * check out, the "baseline" tree of what was checked out previously, the - * working directory for actual files, and the index for staged changes. - * - * You give checkout one of four strategies for update: - * - * - `GIT_CHECKOUT_NONE` is a dry-run strategy that checks for conflicts, - * etc., but doesn't make any actual changes. - * - * - `GIT_CHECKOUT_FORCE` is at the opposite extreme, taking any action to - * make the working directory match the target (including potentially - * discarding modified files). - * - * In between those are `GIT_CHECKOUT_SAFE` and `GIT_CHECKOUT_SAFE_CREATE` - * both of which only make modifications that will not lose changes. - * - * | target == baseline | target != baseline | - * ---------------------|-----------------------|----------------------| - * workdir == baseline | no action | create, update, or | - * | | delete file | - * ---------------------|-----------------------|----------------------| - * workdir exists and | no action | conflict (notify | - * is != baseline | notify dirty MODIFIED | and cancel checkout) | - * ---------------------|-----------------------|----------------------| - * workdir missing, | create if SAFE_CREATE | create file | - * baseline present | notify dirty DELETED | | - * ---------------------|-----------------------|----------------------| - * - * The only difference between SAFE and SAFE_CREATE is that SAFE_CREATE - * will cause a file to be checked out if it is missing from the working - * directory even if it is not modified between the target and baseline. - * - * - * To emulate `git checkout`, use `GIT_CHECKOUT_SAFE` with a checkout - * notification callback (see below) that displays information about dirty - * files. The default behavior will cancel checkout on conflicts. - * - * To emulate `git checkout-index`, use `GIT_CHECKOUT_SAFE_CREATE` with a - * notification callback that cancels the operation if a dirty-but-existing - * file is found in the working directory. This core git command isn't - * quite "force" but is sensitive about some types of changes. - * - * To emulate `git checkout -f`, use `GIT_CHECKOUT_FORCE`. - * - * To emulate `git clone` use `GIT_CHECKOUT_SAFE_CREATE` in the options. - * - * - * There are some additional flags to modified the behavior of checkout: - * - * - GIT_CHECKOUT_ALLOW_CONFLICTS makes SAFE mode apply safe file updates - * even if there are conflicts (instead of cancelling the checkout). - * - * - GIT_CHECKOUT_REMOVE_UNTRACKED means remove untracked files (i.e. not - * in target, baseline, or index, and not ignored) from the working dir. - * - * - GIT_CHECKOUT_REMOVE_IGNORED means remove ignored files (that are also - * untracked) from the working directory as well. - * - * - GIT_CHECKOUT_UPDATE_ONLY means to only update the content of files that - * already exist. Files will not be created nor deleted. This just skips - * applying adds, deletes, and typechanges. - * - * - GIT_CHECKOUT_DONT_UPDATE_INDEX prevents checkout from writing the - * updated files' information to the index. - * - * - Normally, checkout will reload the index and git attributes from disk - * before any operations. GIT_CHECKOUT_NO_REFRESH prevents this reload. - * - * - Unmerged index entries are conflicts. GIT_CHECKOUT_SKIP_UNMERGED skips - * files with unmerged index entries instead. GIT_CHECKOUT_USE_OURS and - * GIT_CHECKOUT_USE_THEIRS to proceed with the checkout using either the - * stage 2 ("ours") or stage 3 ("theirs") version of files in the index. - */ -typedef enum { - GIT_CHECKOUT_NONE = 0, /** default is a dry run, no actual updates */ - - /** Allow safe updates that cannot overwrite uncommitted data */ - GIT_CHECKOUT_SAFE = (1u << 0), - - /** Allow safe updates plus creation of missing files */ - GIT_CHECKOUT_SAFE_CREATE = (1u << 1), - - /** Allow all updates to force working directory to look like index */ - GIT_CHECKOUT_FORCE = (1u << 2), - - - /** Allow checkout to make safe updates even if conflicts are found */ - GIT_CHECKOUT_ALLOW_CONFLICTS = (1u << 4), - - /** Remove untracked files not in index (that are not ignored) */ - GIT_CHECKOUT_REMOVE_UNTRACKED = (1u << 5), - - /** Remove ignored files not in index */ - GIT_CHECKOUT_REMOVE_IGNORED = (1u << 6), - - /** Only update existing files, don't create new ones */ - GIT_CHECKOUT_UPDATE_ONLY = (1u << 7), - - /** Normally checkout updates index entries as it goes; this stops that */ - GIT_CHECKOUT_DONT_UPDATE_INDEX = (1u << 8), - - /** Don't refresh index/config/etc before doing checkout */ - GIT_CHECKOUT_NO_REFRESH = (1u << 9), - - /** - * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED - */ - - /** Allow checkout to skip unmerged files (NOT IMPLEMENTED) */ - GIT_CHECKOUT_SKIP_UNMERGED = (1u << 10), - /** For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) */ - GIT_CHECKOUT_USE_OURS = (1u << 11), - /** For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) */ - GIT_CHECKOUT_USE_THEIRS = (1u << 12), - - /** Recursively checkout submodules with same options (NOT IMPLEMENTED) */ - GIT_CHECKOUT_UPDATE_SUBMODULES = (1u << 16), - /** Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */ - GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1u << 17), - -} git_checkout_strategy_t; - -/** - * Checkout notification flags - * - * Checkout will invoke an options notification callback (`notify_cb`) for - * certain cases - you pick which ones via `notify_flags`: - * - * - GIT_CHECKOUT_NOTIFY_CONFLICT invokes checkout on conflicting paths. - * - * - GIT_CHECKOUT_NOTIFY_DIRTY notifies about "dirty" files, i.e. those that - * do not need an update but no longer match the baseline. Core git - * displays these files when checkout runs, but won't stop the checkout. - * - * - GIT_CHECKOUT_NOTIFY_UPDATED sends notification for any file changed. - * - * - GIT_CHECKOUT_NOTIFY_UNTRACKED notifies about untracked files. - * - * - GIT_CHECKOUT_NOTIFY_IGNORED notifies about ignored files. - * - * Returning a non-zero value from this callback will cancel the checkout. - * Notification callbacks are made prior to modifying any files on disk. - */ -typedef enum { - GIT_CHECKOUT_NOTIFY_NONE = 0, - GIT_CHECKOUT_NOTIFY_CONFLICT = (1u << 0), - GIT_CHECKOUT_NOTIFY_DIRTY = (1u << 1), - GIT_CHECKOUT_NOTIFY_UPDATED = (1u << 2), - GIT_CHECKOUT_NOTIFY_UNTRACKED = (1u << 3), - GIT_CHECKOUT_NOTIFY_IGNORED = (1u << 4), -} git_checkout_notify_t; - -/** Checkout notification callback function */ -typedef int (*git_checkout_notify_cb)( - git_checkout_notify_t why, - const char *path, - const git_diff_file *baseline, - const git_diff_file *target, - const git_diff_file *workdir, - void *payload); - -/** Checkout progress notification function */ -typedef void (*git_checkout_progress_cb)( - const char *path, - size_t completed_steps, - size_t total_steps, - void *payload); - -/** - * Checkout options structure - * - * Zero out for defaults. Initialize with `GIT_CHECKOUT_OPTS_INIT` macro to - * correctly set the `version` field. E.g. - * - * git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; - */ -typedef struct git_checkout_opts { - unsigned int version; - - unsigned int checkout_strategy; /** default will be a dry run */ - - int disable_filters; /** don't apply filters like CRLF conversion */ - unsigned int dir_mode; /** default is 0755 */ - unsigned int file_mode; /** default is 0644 or 0755 as dictated by blob */ - int file_open_flags; /** default is O_CREAT | O_TRUNC | O_WRONLY */ - - unsigned int notify_flags; /** see `git_checkout_notify_t` above */ - git_checkout_notify_cb notify_cb; - void *notify_payload; - - /* Optional callback to notify the consumer of checkout progress. */ - git_checkout_progress_cb progress_cb; - void *progress_payload; - - /** When not zeroed out, array of fnmatch patterns specifying which - * paths should be taken into account, otherwise all files. - */ - git_strarray paths; - - git_tree *baseline; /** expected content of workdir, defaults to HEAD */ -} git_checkout_opts; - -#define GIT_CHECKOUT_OPTS_VERSION 1 -#define GIT_CHECKOUT_OPTS_INIT {GIT_CHECKOUT_OPTS_VERSION} - -/** - * Updates files in the index and the working tree to match the content of - * the commit pointed at by HEAD. - * - * @param repo repository to check out (must be non-bare) - * @param opts specifies checkout options (may be NULL) - * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing - * branch, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_checkout_head( - git_repository *repo, - git_checkout_opts *opts); - -/** - * Updates files in the working tree to match the content of the index. - * - * @param repo repository into which to check out (must be non-bare) - * @param index index to be checked out (or NULL to use repository index) - * @param opts specifies checkout options (may be NULL) - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_checkout_index( - git_repository *repo, - git_index *index, - git_checkout_opts *opts); - -/** - * Updates files in the index and working tree to match the content of the - * tree pointed at by the treeish. - * - * @param repo repository to check out (must be non-bare) - * @param treeish a commit, tag or tree which content will be used to update - * the working directory - * @param opts specifies checkout options (may be NULL) - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_checkout_tree( - git_repository *repo, - const git_object *treeish, - git_checkout_opts *opts); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/clone.h b/git2/include/git2/clone.h deleted file mode 100644 index e299c155d..000000000 --- a/git2/include/git2/clone.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_clone_h__ -#define INCLUDE_git_clone_h__ - -#include "common.h" -#include "types.h" -#include "indexer.h" -#include "checkout.h" -#include "remote.h" - - -/** - * @file git2/clone.h - * @brief Git cloning routines - * @defgroup git_clone Git cloning routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Clone options structure - * - * Use zeros to indicate default settings. It's easiest to use the - * `GIT_CLONE_OPTIONS_INIT` macro: - * - * git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - * - * - `checkout_opts` is options for the checkout step. To disable checkout, - * set the `checkout_strategy` to GIT_CHECKOUT_DEFAULT. - * - `bare` should be set to zero to create a standard repo, non-zero for - * a bare repo - * - `fetch_progress_cb` is optional callback for fetch progress. Be aware that - * this is called inline with network and indexing operations, so performance - * may be affected. - * - `fetch_progress_payload` is payload for fetch_progress_cb - * - * ** "origin" remote options: ** - * - `remote_name` is the name given to the "origin" remote. The default is - * "origin". - * - `pushurl` is a URL to be used for pushing. NULL means use the fetch url. - * - `fetch_spec` is the fetch specification to be used for fetching. NULL - * results in the same behavior as GIT_REMOTE_DEFAULT_FETCH. - * - `push_spec` is the fetch specification to be used for pushing. NULL means - * use the same spec as for fetching. - * - `cred_acquire_cb` is a callback to be used if credentials are required - * during the initial fetch. - * - `cred_acquire_payload` is the payload for the above callback. - * - `transport` is a custom transport to be used for the initial fetch. NULL - * means use the transport autodetected from the URL. - * - `remote_callbacks` may be used to specify custom progress callbacks for - * the origin remote before the fetch is initiated. - * - `remote_autotag` may be used to specify the autotag setting before the - * initial fetch. - */ - -typedef struct git_clone_options { - unsigned int version; - - git_checkout_opts checkout_opts; - int bare; - git_transfer_progress_callback fetch_progress_cb; - void *fetch_progress_payload; - - const char *remote_name; - const char *pushurl; - const char *fetch_spec; - const char *push_spec; - git_cred_acquire_cb cred_acquire_cb; - void *cred_acquire_payload; - git_transport *transport; - git_remote_callbacks *remote_callbacks; - git_remote_autotag_option_t remote_autotag; -} git_clone_options; - -#define GIT_CLONE_OPTIONS_VERSION 1 -#define GIT_CLONE_OPTIONS_INIT {GIT_CLONE_OPTIONS_VERSION, {GIT_CHECKOUT_OPTS_VERSION, GIT_CHECKOUT_SAFE}} - -/** - * Clone a remote repository, and checkout the branch pointed to by the remote - * HEAD. - * - * @param out pointer that will receive the resulting repository object - * @param origin_remote a remote which will act as the initial fetch source - * @param local_path local directory to clone to - * @param options configuration options for the clone. If NULL, the function - * works as though GIT_OPTIONS_INIT were passed. - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_clone( - git_repository **out, - const char *url, - const char *local_path, - const git_clone_options *options); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/commit.h b/git2/include/git2/commit.h deleted file mode 100644 index 764053eaa..000000000 --- a/git2/include/git2/commit.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_commit_h__ -#define INCLUDE_git_commit_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/commit.h - * @brief Git commit parsing, formatting routines - * @defgroup git_commit Git commit parsing, formatting routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a commit object from a repository. - * - * @param commit pointer to the looked up commit - * @param repo the repo to use when locating the commit. - * @param id identity of the commit to locate. If the object is - * an annotated tag it will be peeled back to the commit. - * @return 0 or an error code - */ -GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)commit, repo, id, GIT_OBJ_COMMIT); -} - -/** - * Lookup a commit object from a repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param commit pointer to the looked up commit - * @param repo the repo to use when locating the commit. - * @param id identity of the commit to locate. If the object is - * an annotated tag it will be peeled back to the commit. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)commit, repo, id, len, GIT_OBJ_COMMIT); -} - -/** - * Close an open commit - * - * This is a wrapper around git_object_free() - * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a commit. Failure to do so will cause a memory leak. - * - * @param commit the commit to close - */ - -GIT_INLINE(void) git_commit_free(git_commit *commit) -{ - git_object_free((git_object *) commit); -} - -/** - * Get the id of a commit. - * - * @param commit a previously loaded commit. - * @return object identity for the commit. - */ -GIT_INLINE(const git_oid *) git_commit_id(const git_commit *commit) -{ - return git_object_id((const git_object *)commit); -} - -/** - * Get the encoding for the message of a commit, - * as a string representing a standard encoding name. - * - * The encoding may be NULL if the `encoding` header - * in the commit is missing; in that case UTF-8 is assumed. - * - * @param commit a previously loaded commit. - * @return NULL, or the encoding - */ -GIT_EXTERN(const char *) git_commit_message_encoding(const git_commit *commit); - -/** - * Get the full message of a commit. - * - * @param commit a previously loaded commit. - * @return the message of a commit - */ -GIT_EXTERN(const char *) git_commit_message(const git_commit *commit); - -/** - * Get the commit time (i.e. committer time) of a commit. - * - * @param commit a previously loaded commit. - * @return the time of a commit - */ -GIT_EXTERN(git_time_t) git_commit_time(const git_commit *commit); - -/** - * Get the commit timezone offset (i.e. committer's preferred timezone) of a commit. - * - * @param commit a previously loaded commit. - * @return positive or negative timezone offset, in minutes from UTC - */ -GIT_EXTERN(int) git_commit_time_offset(const git_commit *commit); - -/** - * Get the committer of a commit. - * - * @param commit a previously loaded commit. - * @return the committer of a commit - */ -GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit); - -/** - * Get the author of a commit. - * - * @param commit a previously loaded commit. - * @return the author of a commit - */ -GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit); - -/** - * Get the tree pointed to by a commit. - * - * @param tree_out pointer where to store the tree object - * @param commit a previously loaded commit. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, const git_commit *commit); - -/** - * Get the id of the tree pointed to by a commit. This differs from - * `git_commit_tree` in that no attempts are made to fetch an object - * from the ODB. - * - * @param commit a previously loaded commit. - * @return the id of tree pointed to by commit. - */ -GIT_EXTERN(const git_oid *) git_commit_tree_id(const git_commit *commit); - -/** - * Get the number of parents of this commit - * - * @param commit a previously loaded commit. - * @return integer of count of parents - */ -GIT_EXTERN(unsigned int) git_commit_parentcount(const git_commit *commit); - -/** - * Get the specified parent of the commit. - * - * @param out Pointer where to store the parent commit - * @param commit a previously loaded commit. - * @param n the position of the parent (from 0 to `parentcount`) - * @return 0 or an error code - */ -GIT_EXTERN(int) git_commit_parent(git_commit **out, git_commit *commit, unsigned int n); - -/** - * Get the oid of a specified parent for a commit. This is different from - * `git_commit_parent`, which will attempt to load the parent commit from - * the ODB. - * - * @param commit a previously loaded commit. - * @param n the position of the parent (from 0 to `parentcount`) - * @return the id of the parent, NULL on error. - */ -GIT_EXTERN(const git_oid *) git_commit_parent_id(git_commit *commit, unsigned int n); - -/** - * Get the commit object that is the th generation ancestor - * of the named commit object, following only the first parents. - * The returned commit has to be freed by the caller. - * - * Passing `0` as the generation number returns another instance of the - * base commit itself. - * - * @param ancestor Pointer where to store the ancestor commit - * @param commit a previously loaded commit. - * @param n the requested generation - * @return 0 on success; GIT_ENOTFOUND if no matching ancestor exists - * or an error code - */ -GIT_EXTERN(int) git_commit_nth_gen_ancestor( - git_commit **ancestor, - const git_commit *commit, - unsigned int n); - -/** - * Create a new commit in the repository using `git_object` - * instances as parameters. - * - * The message will not be cleaned up. This can be achieved - * through `git_message_prettify()`. - * - * @param id Pointer where to store the OID of the - * newly created commit - * - * @param repo Repository where to store the commit - * - * @param update_ref If not NULL, name of the reference that - * will be updated to point to this commit. If the reference - * is not direct, it will be resolved to a direct reference. - * Use "HEAD" to update the HEAD of the current branch and - * make it point to this commit. If the reference doesn't - * exist yet, it will be created. - * - * @param author Signature representing the author and the authory - * time of this commit - * - * @param committer Signature representing the committer and the - * commit time of this commit - * - * @param message_encoding The encoding for the message in the - * commit, represented with a standard encoding name. - * E.g. "UTF-8". If NULL, no encoding header is written and - * UTF-8 is assumed. - * - * @param message Full message for this commit - * - * @param tree An instance of a `git_tree` object that will - * be used as the tree for the commit. This tree object must - * also be owned by the given `repo`. - * - * @param parent_count Number of parents for this commit - * - * @param parents[] Array of `parent_count` pointers to `git_commit` - * objects that will be used as the parents for this commit. This - * array may be NULL if `parent_count` is 0 (root commit). All the - * given commits must be owned by the `repo`. - * - * @return 0 or an error code - * The created commit will be written to the Object Database and - * the given reference will be updated to point to it - */ -GIT_EXTERN(int) git_commit_create( - git_oid *id, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - const git_commit *parents[]); - -/** - * Create a new commit in the repository using a variable - * argument list. - * - * The message will be cleaned up from excess whitespace - * it will be made sure that the last line ends with a '\n'. - * - * The parents for the commit are specified as a variable - * list of pointers to `const git_commit *`. Note that this - * is a convenience method which may not be safe to export - * for certain languages or compilers - * - * All other parameters remain the same - * - * @see git_commit_create - */ -GIT_EXTERN(int) git_commit_create_v( - git_oid *id, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - ...); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/common.h b/git2/include/git2/common.h deleted file mode 100644 index 7a4c54c10..000000000 --- a/git2/include/git2/common.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_common_h__ -#define INCLUDE_git_common_h__ - -#include -#include - -#ifdef _MSC_VER -# include "inttypes.h" -#else -# include -#endif - -#ifdef __cplusplus -# define GIT_BEGIN_DECL extern "C" { -# define GIT_END_DECL } -#else - /** Start declarations in C mode */ -# define GIT_BEGIN_DECL /* empty */ - /** End declarations in C mode */ -# define GIT_END_DECL /* empty */ -#endif - -/** Declare a public function exported for application use. */ -#if __GNUC__ >= 4 -# define GIT_EXTERN(type) extern \ - __attribute__((visibility("default"))) \ - type -#elif defined(_MSC_VER) -# define GIT_EXTERN(type) __declspec(dllexport) type -#else -# define GIT_EXTERN(type) extern type -#endif - -/** Declare a function as always inlined. */ -#if defined(_MSC_VER) -# define GIT_INLINE(type) static __inline type -#else -# define GIT_INLINE(type) static inline type -#endif - -/** Declare a function's takes printf style arguments. */ -#ifdef __GNUC__ -# define GIT_FORMAT_PRINTF(a,b) __attribute__((format (printf, a, b))) -#else -# define GIT_FORMAT_PRINTF(a,b) /* empty */ -#endif - -#if (defined(_WIN32)) && !defined(__CYGWIN__) -#define GIT_WIN32 1 -#endif - -#ifdef __amigaos4__ -#include -#endif - -/** - * @file git2/common.h - * @brief Git common platform definitions - * @defgroup git_common Git common platform definitions - * @ingroup Git - * @{ - */ - -GIT_BEGIN_DECL - -/** - * The separator used in path list strings (ie like in the PATH - * environment variable). A semi-colon ";" is used on Windows, and - * a colon ":" for all other systems. - */ -#ifdef GIT_WIN32 -#define GIT_PATH_LIST_SEPARATOR ';' -#else -#define GIT_PATH_LIST_SEPARATOR ':' -#endif - -/** - * The maximum length of a valid git path. - */ -#define GIT_PATH_MAX 4096 - -/** - * The string representation of the null object ID. - */ -#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000" - -/** - * Return the version of the libgit2 library - * being currently used. - * - * @param major Store the major version number - * @param minor Store the minor version number - * @param rev Store the revision (patch) number - */ -GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev); - -/** - * Combinations of these values describe the capabilities of libgit2. - */ -enum { - GIT_CAP_THREADS = ( 1 << 0 ), - GIT_CAP_HTTPS = ( 1 << 1 ) -}; - -/** - * Query compile time options for libgit2. - * - * @return A combination of GIT_CAP_* values. - * - * - GIT_CAP_THREADS - * Libgit2 was compiled with thread support. Note that thread support is still to be seen as a - * 'work in progress'. - * - * - GIT_CAP_HTTPS - * Libgit2 supports the https:// protocol. This requires the open ssl library to be - * found when compiling libgit2. - */ -GIT_EXTERN(int) git_libgit2_capabilities(void); - -/** @} */ -GIT_END_DECL - -#endif diff --git a/git2/include/git2/config.h b/git2/include/git2/config.h deleted file mode 100644 index 19d4cb78d..000000000 --- a/git2/include/git2/config.h +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_config_h__ -#define INCLUDE_git_config_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/config.h - * @brief Git config management routines - * @defgroup git_config Git config management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Priority level of a config file. - * These priority levels correspond to the natural escalation logic - * (from higher to lower) when searching for config entries in git.git. - * - * git_config_open_default() and git_repository_config() honor those - * priority levels as well. - */ -enum { - GIT_CONFIG_LEVEL_SYSTEM = 1, /**< System-wide configuration file. */ - GIT_CONFIG_LEVEL_XDG = 2, /**< XDG compatible configuration file (.config/git/config). */ - GIT_CONFIG_LEVEL_GLOBAL = 3, /**< User-specific configuration file, also called Global configuration file. */ - GIT_CONFIG_LEVEL_LOCAL = 4, /**< Repository specific configuration file. */ - GIT_CONFIG_HIGHEST_LEVEL = -1, /**< Represents the highest level of a config file. */ -}; - -typedef struct { - const char *name; - const char *value; - unsigned int level; -} git_config_entry; - -typedef int (*git_config_foreach_cb)(const git_config_entry *, void *); - - -/** - * Generic backend that implements the interface to - * access a configuration file - */ -struct git_config_backend { - unsigned int version; - struct git_config *cfg; - - /* Open means open the file/database and parse if necessary */ - int (*open)(struct git_config_backend *, unsigned int level); - int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry); - int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload); - int (*set)(struct git_config_backend *, const char *key, const char *value); - int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value); - int (*del)(struct git_config_backend *, const char *key); - int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload); - int (*refresh)(struct git_config_backend *); - void (*free)(struct git_config_backend *); -}; -#define GIT_CONFIG_BACKEND_VERSION 1 -#define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION} - -typedef enum { - GIT_CVAR_FALSE = 0, - GIT_CVAR_TRUE = 1, - GIT_CVAR_INT32, - GIT_CVAR_STRING -} git_cvar_t; - -typedef struct { - git_cvar_t cvar_type; - const char *str_match; - int map_value; -} git_cvar_map; - -/** - * Locate the path to the global configuration file - * - * The user or global configuration file is usually - * located in `$HOME/.gitconfig`. - * - * This method will try to guess the full path to that - * file, if the file exists. The returned path - * may be used on any `git_config` call to load the - * global configuration file. - * - * This method will not guess the path to the xdg compatible - * config file (.config/git/config). - * - * @param out Buffer to store the path in - * @param length size of the buffer in bytes - * @return 0 if a global configuration file has been found. Its path will be stored in `buffer`. - */ -GIT_EXTERN(int) git_config_find_global(char *out, size_t length); - -/** - * Locate the path to the global xdg compatible configuration file - * - * The xdg compatible configuration file is usually - * located in `$HOME/.config/git/config`. - * - * This method will try to guess the full path to that - * file, if the file exists. The returned path - * may be used on any `git_config` call to load the - * xdg compatible configuration file. - * - * @param out Buffer to store the path in - * @param length size of the buffer in bytes - * @return 0 if a xdg compatible configuration file has been - * found. Its path will be stored in `buffer`. - */ -GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length); - -/** - * Locate the path to the system configuration file - * - * If /etc/gitconfig doesn't exist, it will look for - * %PROGRAMFILES%\Git\etc\gitconfig. - - * @param global_config_path Buffer to store the path in - * @param length size of the buffer in bytes - * @return 0 if a system configuration file has been - * found. Its path will be stored in `buffer`. - */ -GIT_EXTERN(int) git_config_find_system(char *out, size_t length); - -/** - * Open the global, XDG and system configuration files - * - * Utility wrapper that finds the global, XDG and system configuration files - * and opens them into a single prioritized config object that can be - * used when accessing default config data outside a repository. - * - * @param out Pointer to store the config instance - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_open_default(git_config **out); - -/** - * Allocate a new configuration object - * - * This object is empty, so you have to add a file to it before you - * can do anything with it. - * - * @param out pointer to the new configuration - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_new(git_config **out); - -/** - * Add a generic config file instance to an existing config - * - * Note that the configuration object will free the file - * automatically. - * - * Further queries on this config object will access each - * of the config file instances in order (instances with - * a higher priority level will be accessed first). - * - * @param cfg the configuration to add the file to - * @param file the configuration file (backend) to add - * @param level the priority level of the backend - * @param force if a config file already exists for the given - * priority level, replace it - * @return 0 on success, GIT_EEXISTS when adding more than one file - * for a given priority level (and force_replace set to 0), or error code - */ -GIT_EXTERN(int) git_config_add_backend( - git_config *cfg, - git_config_backend *file, - unsigned int level, - int force); - -/** - * Add an on-disk config file instance to an existing config - * - * The on-disk file pointed at by `path` will be opened and - * parsed; it's expected to be a native Git config file following - * the default Git config syntax (see man git-config). - * - * Note that the configuration object will free the file - * automatically. - * - * Further queries on this config object will access each - * of the config file instances in order (instances with - * a higher priority level will be accessed first). - * - * @param cfg the configuration to add the file to - * @param path path to the configuration file (backend) to add - * @param level the priority level of the backend - * @param force if a config file already exists for the given - * priority level, replace it - * @return 0 on success, GIT_EEXISTS when adding more than one file - * for a given priority level (and force_replace set to 0), - * GIT_ENOTFOUND when the file doesn't exist or error code - */ -GIT_EXTERN(int) git_config_add_file_ondisk( - git_config *cfg, - const char *path, - unsigned int level, - int force); - -/** - * Create a new config instance containing a single on-disk file - * - * This method is a simple utility wrapper for the following sequence - * of calls: - * - git_config_new - * - git_config_add_file_ondisk - * - * @param out The configuration instance to create - * @param path Path to the on-disk file to open - * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist - * or an error code - */ -GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path); - -/** - * Build a single-level focused config object from a multi-level one. - * - * The returned config object can be used to perform get/set/delete operations - * on a single specific level. - * - * Getting several times the same level from the same parent multi-level config - * will return different config instances, but containing the same config_file - * instance. - * - * @param out The configuration instance to create - * @param parent Multi-level config to search for the given level - * @param level Configuration level to search for - * @return 0, GIT_ENOTFOUND if the passed level cannot be found in the - * multi-level parent config, or an error code - */ -GIT_EXTERN(int) git_config_open_level( - git_config **out, - const git_config *parent, - unsigned int level); - -/** - * Reload changed config files - * - * A config file may be changed on disk out from under the in-memory - * config object. This function causes us to look for files that have - * been modified since we last loaded them and refresh the config with - * the latest information. - * - * @param cfg The configuration to refresh - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_refresh(git_config *cfg); - -/** - * Free the configuration and its associated memory and files - * - * @param cfg the configuration to free - */ -GIT_EXTERN(void) git_config_free(git_config *cfg); - -/** - * Get the git_config_entry of a config variable. - * - * The git_config_entry is owned by the config and should not be freed by the - * user. - - * @param out pointer to the variable git_config_entry - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_entry( - const git_config_entry **out, - const git_config *cfg, - const char *name); - -/** - * Get the value of an integer config variable. - * - * All config files will be looked into, in the order of their - * defined level. A higher level means a higher priority. The - * first occurence of the variable will be returned here. - * - * @param out pointer to the variable where the value should be stored - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_int32(int32_t *out, const git_config *cfg, const char *name); - -/** - * Get the value of a long integer config variable. - * - * All config files will be looked into, in the order of their - * defined level. A higher level means a higher priority. The - * first occurrence of the variable will be returned here. - * - * @param out pointer to the variable where the value should be stored - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_int64(int64_t *out, const git_config *cfg, const char *name); - -/** - * Get the value of a boolean config variable. - * - * This function uses the usual C convention of 0 being false and - * anything else true. - * - * All config files will be looked into, in the order of their - * defined level. A higher level means a higher priority. The - * first occurrence of the variable will be returned here. - * - * @param out pointer to the variable where the value should be stored - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name); - -/** - * Get the value of a string config variable. - * - * The string is owned by the variable and should not be freed by the - * user. - * - * All config files will be looked into, in the order of their - * defined level. A higher level means a higher priority. The - * first occurrence of the variable will be returned here. - * - * @param out pointer to the variable's value - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name); - -/** - * Get each value of a multivar. - * - * The callback will be called on each variable found - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param regexp regular expression to filter which variables we're - * interested in. Use NULL to indicate all - * @param fn the function to be called on each value of the variable - * @param data opaque pointer to pass to the callback - */ -GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload); - -/** - * Set the value of an integer config variable in the config file - * with the highest level (usually the local one). - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value Integer value for the variable - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value); - -/** - * Set the value of a long integer config variable in the config file - * with the highest level (usually the local one). - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value Long integer value for the variable - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value); - -/** - * Set the value of a boolean config variable in the config file - * with the highest level (usually the local one). - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value the value to store - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value); - -/** - * Set the value of a string config variable in the config file - * with the highest level (usually the local one). - * - * A copy of the string is made and the user is free to use it - * afterwards. - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value the string to store. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value); - -/** - * Set a multivar in the local config file. - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param regexp a regular expression to indicate which values to replace - * @param value the new value. - */ -GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value); - -/** - * Delete a config variable from the config file - * with the highest level (usually the local one). - * - * @param cfg the configuration - * @param name the variable to delete - */ -GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name); - -/** - * Perform an operation on each config variable. - * - * The callback receives the normalized name and value of each variable - * in the config backend, and the data pointer passed to this function. - * As soon as one of the callback functions returns something other than 0, - * this function stops iterating and returns `GIT_EUSER`. - * - * @param cfg where to get the variables from - * @param callback the function to call on each variable - * @param payload the data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_config_foreach( - const git_config *cfg, - git_config_foreach_cb callback, - void *payload); - -/** - * Perform an operation on each config variable matching a regular expression. - * - * This behaviors like `git_config_foreach` with an additional filter of a - * regular expression that filters which config keys are passed to the - * callback. - * - * @param cfg where to get the variables from - * @param regexp regular expression to match against config names - * @param callback the function to call on each variable - * @param payload the data to pass to the callback - * @return 0 or the return value of the callback which didn't return 0 - */ -GIT_EXTERN(int) git_config_foreach_match( - const git_config *cfg, - const char *regexp, - git_config_foreach_cb callback, - void *payload); - -/** - * Query the value of a config variable and return it mapped to - * an integer constant. - * - * This is a helper method to easily map different possible values - * to a variable to integer constants that easily identify them. - * - * A mapping array looks as follows: - * - * git_cvar_map autocrlf_mapping[] = { - * {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE}, - * {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE}, - * {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}, - * {GIT_CVAR_STRING, "default", GIT_AUTO_CRLF_DEFAULT}}; - * - * On any "false" value for the variable (e.g. "false", "FALSE", "no"), the - * mapping will store `GIT_AUTO_CRLF_FALSE` in the `out` parameter. - * - * The same thing applies for any "true" value such as "true", "yes" or "1", storing - * the `GIT_AUTO_CRLF_TRUE` variable. - * - * Otherwise, if the value matches the string "input" (with case insensitive comparison), - * the given constant will be stored in `out`, and likewise for "default". - * - * If not a single match can be made to store in `out`, an error code will be - * returned. - * - * @param out place to store the result of the mapping - * @param cfg config file to get the variables from - * @param name name of the config variable to lookup - * @param maps array of `git_cvar_map` objects specifying the possible mappings - * @param map_n number of mapping objects in `maps` - * @return 0 on success, error code otherwise - */ -GIT_EXTERN(int) git_config_get_mapped( - int *out, - const git_config *cfg, - const char *name, - const git_cvar_map *maps, - size_t map_n); - -/** - * Maps a string value to an integer constant - * - * @param out place to store the result of the parsing - * @param maps array of `git_cvar_map` objects specifying the possible mappings - * @param map_n number of mapping objects in `maps` - * @param value value to parse - */ -GIT_EXTERN(int) git_config_lookup_map_value( - int *out, - const git_cvar_map *maps, - size_t map_n, - const char *value); - -/** - * Parse a string value as a bool. - * - * Valid values for true are: 'true', 'yes', 'on', 1 or any - * number different from 0 - * Valid values for false are: 'false', 'no', 'off', 0 - * - * @param out place to store the result of the parsing - * @param value value to parse - */ -GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value); - -/** - * Parse a string value as an int32. - * - * An optional value suffix of 'k', 'm', or 'g' will - * cause the value to be multiplied by 1024, 1048576, - * or 1073741824 prior to output. - * - * @param out place to store the result of the parsing - * @param value value to parse - */ -GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value); - -/** - * Parse a string value as an int64. - * - * An optional value suffix of 'k', 'm', or 'g' will - * cause the value to be multiplied by 1024, 1048576, - * or 1073741824 prior to output. - * - * @param out place to store the result of the parsing - * @param value value to parse - */ -GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); - - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/diff.h b/git2/include/git2/diff.h deleted file mode 100644 index c052f34f8..000000000 --- a/git2/include/git2/diff.h +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_diff_h__ -#define INCLUDE_git_diff_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "tree.h" -#include "refs.h" - -/** - * @file git2/diff.h - * @brief Git tree and file differencing routines. - * - * Overview - * -------- - * - * Calculating diffs is generally done in two phases: building a diff list - * then traversing the diff list. This makes is easier to share logic - * across the various types of diffs (tree vs tree, workdir vs index, etc.), - * and also allows you to insert optional diff list post-processing phases, - * such as rename detected, in between the steps. When you are done with a - * diff list object, it must be freed. - * - * Terminology - * ----------- - * - * To understand the diff APIs, you should know the following terms: - * - * - A `diff` or `diff list` represents the cumulative list of differences - * between two snapshots of a repository (possibly filtered by a set of - * file name patterns). This is the `git_diff_list` object. - * - A `delta` is a file pair with an old and new revision. The old version - * may be absent if the file was just created and the new version may be - * absent if the file was deleted. A diff is mostly just a list of deltas. - * - A `binary` file / delta is a file (or pair) for which no text diffs - * should be generated. A diff list can contain delta entries that are - * binary, but no diff content will be output for those files. There is - * a base heuristic for binary detection and you can further tune the - * behavior with git attributes or diff flags and option settings. - * - A `hunk` is a span of modified lines in a delta along with some stable - * surrounding context. You can configure the amount of context and other - * properties of how hunks are generated. Each hunk also comes with a - * header that described where it starts and ends in both the old and new - * versions in the delta. - * - A `line` is a range of characters inside a hunk. It could be a context - * line (i.e. in both old and new versions), an added line (i.e. only in - * the new version), or a removed line (i.e. only in the old version). - * Unfortunately, we don't know anything about the encoding of data in the - * file being diffed, so we cannot tell you much about the line content. - * Line data will not be NUL-byte terminated, however, because it will be - * just a span of bytes inside the larger file. - * - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Flags for diff options. A combination of these flags can be passed - * in via the `flags` value in the `git_diff_options`. - */ -typedef enum { - /** Normal diff, the default */ - GIT_DIFF_NORMAL = 0, - /** Reverse the sides of the diff */ - GIT_DIFF_REVERSE = (1 << 0), - /** Treat all files as text, disabling binary attributes & detection */ - GIT_DIFF_FORCE_TEXT = (1 << 1), - /** Ignore all whitespace */ - GIT_DIFF_IGNORE_WHITESPACE = (1 << 2), - /** Ignore changes in amount of whitespace */ - GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3), - /** Ignore whitespace at end of line */ - GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4), - /** Exclude submodules from the diff completely */ - GIT_DIFF_IGNORE_SUBMODULES = (1 << 5), - /** Use the "patience diff" algorithm (currently unimplemented) */ - GIT_DIFF_PATIENCE = (1 << 6), - /** Include ignored files in the diff list */ - GIT_DIFF_INCLUDE_IGNORED = (1 << 7), - /** Include untracked files in the diff list */ - GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), - /** Include unmodified files in the diff list */ - GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), - /** Even with the GIT_DIFF_INCLUDE_UNTRACKED flag, when an untracked - * directory is found, only a single entry for the directory is added - * to the diff list; with this flag, all files under the directory will - * be included, too. - */ - GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), - /** If the pathspec is set in the diff options, this flags means to - * apply it as an exact match instead of as an fnmatch pattern. - */ - GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), - /** Use case insensitive filename comparisons */ - GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12), - /** When generating patch text, include the content of untracked files */ - GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13), - /** Disable updating of the `binary` flag in delta records. This is - * useful when iterating over a diff if you don't need hunk and data - * callbacks and want to avoid having to load file completely. - */ - GIT_DIFF_SKIP_BINARY_CHECK = (1 << 14), - /** Normally, a type change between files will be converted into a - * DELETED record for the old and an ADDED record for the new; this - * options enabled the generation of TYPECHANGE delta records. - */ - GIT_DIFF_INCLUDE_TYPECHANGE = (1 << 15), - /** Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still - * generally show as a DELETED blob. This flag tries to correctly - * label blob->tree transitions as TYPECHANGE records with new_file's - * mode set to tree. Note: the tree SHA will not be available. - */ - GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16), - /** Ignore file mode changes */ - GIT_DIFF_IGNORE_FILEMODE = (1 << 17), -} git_diff_option_t; - -/** - * Structure describing options about how the diff should be executed. - * - * Setting all values of the structure to zero will yield the default - * values. Similarly, passing NULL for the options structure will - * give the defaults. The default values are marked below. - * - * - `flags` is a combination of the `git_diff_option_t` values above - * - `context_lines` is the number of unchanged lines that define the - * boundary of a hunk (and to display before and after) - * - `interhunk_lines` is the maximum number of unchanged lines between - * hunk boundaries before the hunks will be merged into a one. - * - `old_prefix` is the virtual "directory" to prefix to old file names - * in hunk headers (default "a") - * - `new_prefix` is the virtual "directory" to prefix to new file names - * in hunk headers (default "b") - * - `pathspec` is an array of paths / fnmatch patterns to constrain diff - * - `max_size` is a file size (in bytes) above which a blob will be marked - * as binary automatically; pass a negative value to disable. - */ -typedef struct { - unsigned int version; /**< version for the struct */ - uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */ - uint16_t context_lines; /**< defaults to 3 */ - uint16_t interhunk_lines; /**< defaults to 0 */ - const char *old_prefix; /**< defaults to "a" */ - const char *new_prefix; /**< defaults to "b" */ - git_strarray pathspec; /**< defaults to include all paths */ - git_off_t max_size; /**< defaults to 512MB */ -} git_diff_options; - -#define GIT_DIFF_OPTIONS_VERSION 1 -#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION} - -/** - * The diff list object that contains all individual file deltas. - * - * This is an opaque structure which will be allocated by one of the diff - * generator functions below (such as `git_diff_tree_to_tree`). You are - * responsible for releasing the object memory when done, using the - * `git_diff_list_free()` function. - */ -typedef struct git_diff_list git_diff_list; - -/** - * Flags for the file object on each side of a diff. - * - * Note: most of these flags are just for **internal** consumption by - * libgit2, but some of them may be interesting to external users. - */ -typedef enum { - GIT_DIFF_FILE_VALID_OID = (1 << 0), /** `oid` value is known correct */ - GIT_DIFF_FILE_FREE_PATH = (1 << 1), /** `path` is allocated memory */ - GIT_DIFF_FILE_BINARY = (1 << 2), /** should be considered binary data */ - GIT_DIFF_FILE_NOT_BINARY = (1 << 3), /** should be considered text data */ - GIT_DIFF_FILE_FREE_DATA = (1 << 4), /** internal file data is allocated */ - GIT_DIFF_FILE_UNMAP_DATA = (1 << 5), /** internal file data is mmap'ed */ - GIT_DIFF_FILE_NO_DATA = (1 << 6), /** file data should not be loaded */ -} git_diff_file_flag_t; - -/** - * What type of change is described by a git_diff_delta? - * - * `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run - * `git_diff_find_similar()` on the diff list object. - * - * `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE` - * in the option flags (otherwise type changes will be split into ADDED / - * DELETED pairs). - */ -typedef enum { - GIT_DELTA_UNMODIFIED = 0, /** no changes */ - GIT_DELTA_ADDED = 1, /** entry does not exist in old version */ - GIT_DELTA_DELETED = 2, /** entry does not exist in new version */ - GIT_DELTA_MODIFIED = 3, /** entry content changed between old and new */ - GIT_DELTA_RENAMED = 4, /** entry was renamed between old and new */ - GIT_DELTA_COPIED = 5, /** entry was copied from another old entry */ - GIT_DELTA_IGNORED = 6, /** entry is ignored item in workdir */ - GIT_DELTA_UNTRACKED = 7, /** entry is untracked item in workdir */ - GIT_DELTA_TYPECHANGE = 8, /** type of entry changed between old and new */ -} git_delta_t; - -/** - * Description of one side of a diff entry. - * - * Although this is called a "file", it may actually represent a file, a - * symbolic link, a submodule commit id, or even a tree (although that only - * if you are tracking type changes or ignored/untracked directories). - * - * The `oid` is the `git_oid` of the item. If the entry represents an - * absent side of a diff (e.g. the `old_file` of a `GIT_DELTA_ADDED` delta), - * then the oid will be zeroes. - * - * `path` is the NUL-terminated path to the entry relative to the working - * directory of the repository. - * - * `size` is the size of the entry in bytes. - * - * `flags` is a combination of the `git_diff_file_flag_t` types, but those - * are largely internal values. - * - * `mode` is, roughly, the stat() `st_mode` value for the item. This will - * be restricted to one of the `git_filemode_t` values. - */ -typedef struct { - git_oid oid; - const char *path; - git_off_t size; - unsigned int flags; - uint16_t mode; -} git_diff_file; - -/** - * Description of changes to one entry. - * - * When iterating over a diff list object, this will be passed to most - * callback functions and you can use the contents to understand exactly - * what has changed. - * - * The `old_file` represents the "from" side of the diff and the `new_file` - * represents to "to" side of the diff. What those means depend on the - * function that was used to generate the diff and will be documented below. - * You can also use the `GIT_DIFF_REVERSE` flag to flip it around. - * - * Although the two sides of the delta are named "old_file" and "new_file", - * they actually may correspond to entries that represent a file, a symbolic - * link, a submodule commit id, or even a tree (if you are tracking type - * changes or ignored/untracked directories). - * - * Under some circumstances, in the name of efficiency, not all fields will - * be filled in, but we generally try to fill in as much as possible. One - * example is that the "binary" field will not examine file contents if you - * do not pass in hunk and/or line callbacks to the diff foreach iteration - * function. It will just use the git attributes for those files. - */ -typedef struct { - git_diff_file old_file; - git_diff_file new_file; - git_delta_t status; - unsigned int similarity; /**< for RENAMED and COPIED, value 0-100 */ - int binary; -} git_diff_delta; - -/** - * When iterating over a diff, callback that will be made per file. - * - * @param delta A pointer to the delta data for the file - * @param progress Goes from 0 to 1 over the diff list - * @param payload User-specified pointer from foreach function - */ -typedef int (*git_diff_file_cb)( - const git_diff_delta *delta, - float progress, - void *payload); - -/** - * Structure describing a hunk of a diff. - */ -typedef struct { - int old_start; /** Starting line number in old_file */ - int old_lines; /** Number of lines in old_file */ - int new_start; /** Starting line number in new_file */ - int new_lines; /** Number of lines in new_file */ -} git_diff_range; - -/** - * When iterating over a diff, callback that will be made per hunk. - */ -typedef int (*git_diff_hunk_cb)( - const git_diff_delta *delta, - const git_diff_range *range, - const char *header, - size_t header_len, - void *payload); - -/** - * Line origin constants. - * - * These values describe where a line came from and will be passed to - * the git_diff_data_cb when iterating over a diff. There are some - * special origin constants at the end that are used for the text - * output callbacks to demarcate lines that are actually part of - * the file or hunk headers. - */ -typedef enum { - /* These values will be sent to `git_diff_data_cb` along with the line */ - GIT_DIFF_LINE_CONTEXT = ' ', - GIT_DIFF_LINE_ADDITION = '+', - GIT_DIFF_LINE_DELETION = '-', - GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< Removed line w/o LF & added one with */ - GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */ - - /* The following values will only be sent to a `git_diff_data_cb` when - * the content of a diff is being formatted (eg. through - * git_diff_print_patch() or git_diff_print_compact(), for instance). - */ - GIT_DIFF_LINE_FILE_HDR = 'F', - GIT_DIFF_LINE_HUNK_HDR = 'H', - GIT_DIFF_LINE_BINARY = 'B' -} git_diff_line_t; - -/** - * When iterating over a diff, callback that will be made per text diff - * line. In this context, the provided range will be NULL. - * - * When printing a diff, callback that will be made to output each line - * of text. This uses some extra GIT_DIFF_LINE_... constants for output - * of lines of file and hunk headers. - */ -typedef int (*git_diff_data_cb)( - const git_diff_delta *delta, /** delta that contains this data */ - const git_diff_range *range, /** range of lines containing this data */ - char line_origin, /** git_diff_list_t value from above */ - const char *content, /** diff data - not NUL terminated */ - size_t content_len, /** number of bytes of diff data */ - void *payload); /** user reference data */ - -/** - * The diff patch is used to store all the text diffs for a delta. - * - * You can easily loop over the content of patches and get information about - * them. - */ -typedef struct git_diff_patch git_diff_patch; - -/** - * Flags to control the behavior of diff rename/copy detection. - */ -typedef enum { - /** look for renames? (`--find-renames`) */ - GIT_DIFF_FIND_RENAMES = (1 << 0), - /** consider old size of modified for renames? (`--break-rewrites=N`) */ - GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1 << 1), - - /** look for copies? (a la `--find-copies`) */ - GIT_DIFF_FIND_COPIES = (1 << 2), - /** consider unmodified as copy sources? (`--find-copies-harder`) */ - GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1 << 3), - - /** split large rewrites into delete/add pairs (`--break-rewrites=/M`) */ - GIT_DIFF_FIND_AND_BREAK_REWRITES = (1 << 4), -} git_diff_find_t; - -/** - * Control behavior of rename and copy detection - */ -typedef struct { - unsigned int version; - - /** Combination of git_diff_find_t values (default FIND_RENAMES) */ - unsigned int flags; - - /** Similarity to consider a file renamed (default 50) */ - unsigned int rename_threshold; - /** Similarity of modified to be eligible rename source (default 50) */ - unsigned int rename_from_rewrite_threshold; - /** Similarity to consider a file a copy (default 50) */ - unsigned int copy_threshold; - /** Similarity to split modify into delete/add pair (default 60) */ - unsigned int break_rewrite_threshold; - - /** Maximum similarity sources to examine (a la diff's `-l` option or - * the `diff.renameLimit` config) (default 200) - */ - unsigned int target_limit; -} git_diff_find_options; - -#define GIT_DIFF_FIND_OPTIONS_VERSION 1 -#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION} - -/** @name Diff List Generator Functions - * - * These are the functions you would use to create (or destroy) a - * git_diff_list from various objects in a repository. - */ -/**@{*/ - -/** - * Deallocate a diff list. - */ -GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff); - -/** - * Create a diff list with the difference between two tree objects. - * - * This is equivalent to `git diff ` - * - * The first tree will be used for the "old_file" side of the delta and the - * second tree will be used for the "new_file" side of the delta. - * - * @param diff Output pointer to a git_diff_list pointer to be allocated. - * @param repo The repository containing the trees. - * @param old_tree A git_tree object to diff from. - * @param new_tree A git_tree object to diff to. - * @param opts Structure with options to influence diff or NULL for defaults. - */ -GIT_EXTERN(int) git_diff_tree_to_tree( - git_diff_list **diff, - git_repository *repo, - git_tree *old_tree, - git_tree *new_tree, - const git_diff_options *opts); /**< can be NULL for defaults */ - -/** - * Create a diff list between a tree and repository index. - * - * This is equivalent to `git diff --cached ` or if you pass - * the HEAD tree, then like `git diff --cached`. - * - * The tree you pass will be used for the "old_file" side of the delta, and - * the index will be used for the "new_file" side of the delta. - * - * @param diff Output pointer to a git_diff_list pointer to be allocated. - * @param repo The repository containing the tree and index. - * @param old_tree A git_tree object to diff from. - * @param index The index to diff with; repo index used if NULL. - * @param opts Structure with options to influence diff or NULL for defaults. - */ -GIT_EXTERN(int) git_diff_tree_to_index( - git_diff_list **diff, - git_repository *repo, - git_tree *old_tree, - git_index *index, - const git_diff_options *opts); /**< can be NULL for defaults */ - -/** - * Create a diff list between the repository index and the workdir directory. - * - * This matches the `git diff` command. See the note below on - * `git_diff_tree_to_workdir` for a discussion of the difference between - * `git diff` and `git diff HEAD` and how to emulate a `git diff ` - * using libgit2. - * - * The index will be used for the "old_file" side of the delta, and the - * working directory will be used for the "new_file" side of the delta. - * - * @param diff Output pointer to a git_diff_list pointer to be allocated. - * @param repo The repository. - * @param index The index to diff from; repo index used if NULL. - * @param opts Structure with options to influence diff or NULL for defaults. - */ -GIT_EXTERN(int) git_diff_index_to_workdir( - git_diff_list **diff, - git_repository *repo, - git_index *index, - const git_diff_options *opts); /**< can be NULL for defaults */ - -/** - * Create a diff list between a tree and the working directory. - * - * The tree you provide will be used for the "old_file" side of the delta, - * and the working directory will be used for the "new_file" side. - * - * Please note: this is *NOT* the same as `git diff `. Running - * `git diff HEAD` or the like actually uses information from the index, - * along with the tree and working directory info. - * - * This function returns strictly the differences between the tree and the - * files contained in the working directory, regardless of the state of - * files in the index. It may come as a surprise, but there is no direct - * equivalent in core git. - * - * To emulate `git diff `, call both `git_diff_tree_to_index` and - * `git_diff_index_to_workdir`, then call `git_diff_merge` on the results. - * That will yield a `git_diff_list` that matches the git output. - * - * If this seems confusing, take the case of a file with a staged deletion - * where the file has then been put back into the working dir and modified. - * The tree-to-workdir diff for that file is 'modified', but core git would - * show status 'deleted' since there is a pending deletion in the index. - * - * @param diff A pointer to a git_diff_list pointer that will be allocated. - * @param repo The repository containing the tree. - * @param old_tree A git_tree object to diff from. - * @param opts Structure with options to influence diff or NULL for defaults. - */ -GIT_EXTERN(int) git_diff_tree_to_workdir( - git_diff_list **diff, - git_repository *repo, - git_tree *old_tree, - const git_diff_options *opts); /**< can be NULL for defaults */ - -/** - * Merge one diff list into another. - * - * This merges items from the "from" list into the "onto" list. The - * resulting diff list will have all items that appear in either list. - * If an item appears in both lists, then it will be "merged" to appear - * as if the old version was from the "onto" list and the new version - * is from the "from" list (with the exception that if the item has a - * pending DELETE in the middle, then it will show as deleted). - * - * @param onto Diff to merge into. - * @param from Diff to merge. - */ -GIT_EXTERN(int) git_diff_merge( - git_diff_list *onto, - const git_diff_list *from); - -/** - * Transform a diff list marking file renames, copies, etc. - * - * This modifies a diff list in place, replacing old entries that look - * like renames or copies with new entries reflecting those changes. - * This also will, if requested, break modified files into add/remove - * pairs if the amount of change is above a threshold. - * - * @param diff Diff list to run detection algorithms on - * @param options Control how detection should be run, NULL for defaults - * @return 0 on success, -1 on failure - */ -GIT_EXTERN(int) git_diff_find_similar( - git_diff_list *diff, - git_diff_find_options *options); - -/**@}*/ - - -/** @name Diff List Processor Functions - * - * These are the functions you apply to a diff list to process it - * or read it in some way. - */ -/**@{*/ - -/** - * Loop over all deltas in a diff list issuing callbacks. - * - * This will iterate through all of the files described in a diff. You - * should provide a file callback to learn about each file. - * - * The "hunk" and "line" callbacks are optional, and the text diff of the - * files will only be calculated if they are not NULL. Of course, these - * callbacks will not be invoked for binary files on the diff list or for - * files whose only changed is a file mode change. - * - * Returning a non-zero value from any of the callbacks will terminate - * the iteration and cause this return `GIT_EUSER`. - * - * @param diff A git_diff_list generated by one of the above functions. - * @param file_cb Callback function to make per file in the diff. - * @param hunk_cb Optional callback to make per hunk of text diff. This - * callback is called to describe a range of lines in the - * diff. It will not be issued for binary files. - * @param line_cb Optional callback to make per line of diff text. This - * same callback will be made for context lines, added, and - * removed lines, and even for a deleted trailing newline. - * @param payload Reference pointer that will be passed to your callbacks. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_foreach( - git_diff_list *diff, - git_diff_file_cb file_cb, - git_diff_hunk_cb hunk_cb, - git_diff_data_cb line_cb, - void *payload); - -/** - * Iterate over a diff generating text output like "git diff --name-status". - * - * Returning a non-zero value from the callbacks will terminate the - * iteration and cause this return `GIT_EUSER`. - * - * @param diff A git_diff_list generated by one of the above functions. - * @param print_cb Callback to make per line of diff text. - * @param payload Reference pointer that will be passed to your callback. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_print_compact( - git_diff_list *diff, - git_diff_data_cb print_cb, - void *payload); - -/** - * Look up the single character abbreviation for a delta status code. - * - * When you call `git_diff_print_compact` it prints single letter codes into - * the output such as 'A' for added, 'D' for deleted, 'M' for modified, etc. - * It is sometimes convenient to convert a git_delta_t value into these - * letters for your own purposes. This function does just that. By the - * way, unmodified will return a space (i.e. ' '). - * - * @param delta_t The git_delta_t value to look up - * @return The single character label for that code - */ -GIT_EXTERN(char) git_diff_status_char(git_delta_t status); - -/** - * Iterate over a diff generating text output like "git diff". - * - * This is a super easy way to generate a patch from a diff. - * - * Returning a non-zero value from the callbacks will terminate the - * iteration and cause this return `GIT_EUSER`. - * - * @param diff A git_diff_list generated by one of the above functions. - * @param payload Reference pointer that will be passed to your callbacks. - * @param print_cb Callback function to output lines of the diff. This - * same function will be called for file headers, hunk - * headers, and diff lines. Fortunately, you can probably - * use various GIT_DIFF_LINE constants to determine what - * text you are given. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_print_patch( - git_diff_list *diff, - git_diff_data_cb print_cb, - void *payload); - -/** - * Query how many diff records are there in a diff list. - * - * @param diff A git_diff_list generated by one of the above functions - * @return Count of number of deltas in the list - */ -GIT_EXTERN(size_t) git_diff_num_deltas(git_diff_list *diff); - -/** - * Query how many diff deltas are there in a diff list filtered by type. - * - * This works just like `git_diff_entrycount()` with an extra parameter - * that is a `git_delta_t` and returns just the count of how many deltas - * match that particular type. - * - * @param diff A git_diff_list generated by one of the above functions - * @param type A git_delta_t value to filter the count - * @return Count of number of deltas matching delta_t type - */ -GIT_EXTERN(size_t) git_diff_num_deltas_of_type( - git_diff_list *diff, - git_delta_t type); - -/** - * Return the diff delta and patch for an entry in the diff list. - * - * The `git_diff_patch` is a newly created object contains the text diffs - * for the delta. You have to call `git_diff_patch_free()` when you are - * done with it. You can use the patch object to loop over all the hunks - * and lines in the diff of the one delta. - * - * For an unchanged file or a binary file, no `git_diff_patch` will be - * created, the output will be set to NULL, and the `binary` flag will be - * set true in the `git_diff_delta` structure. - * - * The `git_diff_delta` pointer points to internal data and you do not have - * to release it when you are done with it. It will go away when the - * `git_diff_list` and `git_diff_patch` go away. - * - * It is okay to pass NULL for either of the output parameters; if you pass - * NULL for the `git_diff_patch`, then the text diff will not be calculated. - * - * @param patch_out Output parameter for the delta patch object - * @param delta_out Output parameter for the delta object - * @param diff Diff list object - * @param idx Index into diff list - * @return 0 on success, other value < 0 on error - */ -GIT_EXTERN(int) git_diff_get_patch( - git_diff_patch **patch_out, - const git_diff_delta **delta_out, - git_diff_list *diff, - size_t idx); - -/** - * Free a git_diff_patch object. - */ -GIT_EXTERN(void) git_diff_patch_free( - git_diff_patch *patch); - -/** - * Get the delta associated with a patch - */ -GIT_EXTERN(const git_diff_delta *) git_diff_patch_delta( - git_diff_patch *patch); - -/** - * Get the number of hunks in a patch - */ -GIT_EXTERN(size_t) git_diff_patch_num_hunks( - git_diff_patch *patch); - -/** - * Get the information about a hunk in a patch - * - * Given a patch and a hunk index into the patch, this returns detailed - * information about that hunk. Any of the output pointers can be passed - * as NULL if you don't care about that particular piece of information. - * - * @param range Output pointer to git_diff_range of hunk - * @param header Output pointer to header string for hunk. Unlike the - * content pointer for each line, this will be NUL-terminated - * @param header_len Output value of characters in header string - * @param lines_in_hunk Output count of total lines in this hunk - * @param patch Input pointer to patch object - * @param hunk_idx Input index of hunk to get information about - * @return 0 on success, GIT_ENOTFOUND if hunk_idx out of range, <0 on error - */ -GIT_EXTERN(int) git_diff_patch_get_hunk( - const git_diff_range **range, - const char **header, - size_t *header_len, - size_t *lines_in_hunk, - git_diff_patch *patch, - size_t hunk_idx); - -/** - * Get the number of lines in a hunk. - * - * @param patch The git_diff_patch object - * @param hunk_idx Index of the hunk - * @return Number of lines in hunk or -1 if invalid hunk index - */ -GIT_EXTERN(int) git_diff_patch_num_lines_in_hunk( - git_diff_patch *patch, - size_t hunk_idx); - -/** - * Get data about a line in a hunk of a patch. - * - * Given a patch, a hunk index, and a line index in the hunk, this - * will return a lot of details about that line. If you pass a hunk - * index larger than the number of hunks or a line index larger than - * the number of lines in the hunk, this will return -1. - * - * @param line_origin A GIT_DIFF_LINE constant from above - * @param content Pointer to content of diff line, not NUL-terminated - * @param content_len Number of characters in content - * @param old_lineno Line number in old file or -1 if line is added - * @param new_lineno Line number in new file or -1 if line is deleted - * @param patch The patch to look in - * @param hunk_idx The index of the hunk - * @param line_of_index The index of the line in the hunk - * @return 0 on success, <0 on failure - */ -GIT_EXTERN(int) git_diff_patch_get_line_in_hunk( - char *line_origin, - const char **content, - size_t *content_len, - int *old_lineno, - int *new_lineno, - git_diff_patch *patch, - size_t hunk_idx, - size_t line_of_hunk); - -/** - * Serialize the patch to text via callback. - * - * Returning a non-zero value from the callback will terminate the iteration - * and cause this return `GIT_EUSER`. - * - * @param patch A git_diff_patch representing changes to one file - * @param print_cb Callback function to output lines of the patch. Will be - * called for file headers, hunk headers, and diff lines. - * @param payload Reference pointer that will be passed to your callbacks. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_patch_print( - git_diff_patch *patch, - git_diff_data_cb print_cb, - void *payload); - -/** - * Get the content of a patch as a single diff text. - * - * @param string Allocated string; caller must free. - * @param patch A git_diff_patch representing changes to one file - * @return 0 on success, <0 on failure. - */ -GIT_EXTERN(int) git_diff_patch_to_str( - char **string, - git_diff_patch *patch); - -/**@}*/ - - -/* - * Misc - */ - -/** - * Directly run a diff on two blobs. - * - * Compared to a file, a blob lacks some contextual information. As such, - * the `git_diff_file` given to the callback will have some fake data; i.e. - * `mode` will be 0 and `path` will be NULL. - * - * NULL is allowed for either `old_blob` or `new_blob` and will be treated - * as an empty blob, with the `oid` set to NULL in the `git_diff_file` data. - * - * We do run a binary content check on the two blobs and if either of the - * blobs looks like binary data, the `git_diff_delta` binary attribute will - * be set to 1 and no call to the hunk_cb nor line_cb will be made (unless - * you pass `GIT_DIFF_FORCE_TEXT` of course). - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_blobs( - const git_blob *old_blob, - const git_blob *new_blob, - const git_diff_options *options, - git_diff_file_cb file_cb, - git_diff_hunk_cb hunk_cb, - git_diff_data_cb line_cb, - void *payload); - -/** - * Directly run a diff between a blob and a buffer. - * - * As with `git_diff_blobs`, comparing a blob and buffer lacks some context, - * so the `git_diff_file` parameters to the callbacks will be faked a la the - * rules for `git_diff_blobs()`. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_blob_to_buffer( - const git_blob *old_blob, - const char *buffer, - size_t buffer_len, - const git_diff_options *options, - git_diff_file_cb file_cb, - git_diff_hunk_cb hunk_cb, - git_diff_data_cb data_cb, - void *payload); - -GIT_END_DECL - -/** @} */ - -#endif diff --git a/git2/include/git2/errors.h b/git2/include/git2/errors.h deleted file mode 100644 index 9e0a1a9e6..000000000 --- a/git2/include/git2/errors.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_errors_h__ -#define INCLUDE_git_errors_h__ - -#include "common.h" - -/** - * @file git2/errors.h - * @brief Git error handling routines and variables - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** Generic return codes */ -enum { - GIT_OK = 0, - GIT_ERROR = -1, - GIT_ENOTFOUND = -3, - GIT_EEXISTS = -4, - GIT_EAMBIGUOUS = -5, - GIT_EBUFS = -6, - GIT_EUSER = -7, - GIT_EBAREREPO = -8, - GIT_EORPHANEDHEAD = -9, - GIT_EUNMERGED = -10, - GIT_ENONFASTFORWARD = -11, - GIT_EINVALIDSPEC = -12, - - GIT_PASSTHROUGH = -30, - GIT_ITEROVER = -31, -}; - -typedef struct { - char *message; - int klass; -} git_error; - -/** Error classes */ -typedef enum { - GITERR_NOMEMORY, - GITERR_OS, - GITERR_INVALID, - GITERR_REFERENCE, - GITERR_ZLIB, - GITERR_REPOSITORY, - GITERR_CONFIG, - GITERR_REGEX, - GITERR_ODB, - GITERR_INDEX, - GITERR_OBJECT, - GITERR_NET, - GITERR_TAG, - GITERR_TREE, - GITERR_INDEXER, - GITERR_SSL, - GITERR_SUBMODULE, - GITERR_THREAD, - GITERR_STASH, - GITERR_CHECKOUT, - GITERR_FETCHHEAD, - GITERR_MERGE, -} git_error_t; - -/** - * Return the last `git_error` object that was generated for the - * current thread or NULL if no error has occurred. - * - * @return A git_error object. - */ -GIT_EXTERN(const git_error *) giterr_last(void); - -/** - * Clear the last library error that occurred for this thread. - */ -GIT_EXTERN(void) giterr_clear(void); - -/** - * Set the error message string for this thread. - * - * This function is public so that custom ODB backends and the like can - * relay an error message through libgit2. Most regular users of libgit2 - * will never need to call this function -- actually, calling it in most - * circumstances (for example, calling from within a callback function) - * will just end up having the value overwritten by libgit2 internals. - * - * This error message is stored in thread-local storage and only applies - * to the particular thread that this libgit2 call is made from. - * - * NOTE: Passing the `error_class` as GITERR_OS has a special behavior: we - * attempt to append the system default error message for the last OS error - * that occurred and then clear the last error. The specific implementation - * of looking up and clearing this last OS error will vary by platform. - * - * @param error_class One of the `git_error_t` enum above describing the - * general subsystem that is responsible for the error. - * @param message The formatted error message to keep - */ -GIT_EXTERN(void) giterr_set_str(int error_class, const char *string); - -/** - * Set the error message to a special value for memory allocation failure. - * - * The normal `giterr_set_str()` function attempts to `strdup()` the string - * that is passed in. This is not a good idea when the error in question - * is a memory allocation failure. That circumstance has a special setter - * function that sets the error string to a known and statically allocated - * internal value. - */ -GIT_EXTERN(void) giterr_set_oom(void); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/graph.h b/git2/include/git2/graph.h deleted file mode 100644 index 5850aa6e2..000000000 --- a/git2/include/git2/graph.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_graph_h__ -#define INCLUDE_git_graph_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/graph.h - * @brief Git graph traversal routines - * @defgroup git_revwalk Git graph traversal routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Count the number of unique commits between two commit objects - * - * @param ahead number of commits, starting at `one`, unique from commits in `two` - * @param behind number of commits, starting at `two`, unique from commits in `one` - * @param repo the repository where the commits exist - * @param one one of the commits - * @param two the other commit - */ -GIT_EXTERN(int) git_graph_ahead_behind(size_t *ahead, size_t *behind, git_repository *repo, const git_oid *one, const git_oid *two); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/ignore.h b/git2/include/git2/ignore.h deleted file mode 100644 index d0c1877a8..000000000 --- a/git2/include/git2/ignore.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_ignore_h__ -#define INCLUDE_git_ignore_h__ - -#include "common.h" -#include "types.h" - -GIT_BEGIN_DECL - -/** - * Add ignore rules for a repository. - * - * Excludesfile rules (i.e. .gitignore rules) are generally read from - * .gitignore files in the repository tree or from a shared system file - * only if a "core.excludesfile" config value is set. The library also - * keeps a set of per-repository internal ignores that can be configured - * in-memory and will not persist. This function allows you to add to - * that internal rules list. - * - * Example usage: - * - * error = git_ignore_add_rule(myrepo, "*.c\ndir/\nFile with space\n"); - * - * This would add three rules to the ignores. - * - * @param repo The repository to add ignore rules to. - * @param rules Text of rules, a la the contents of a .gitignore file. - * It is okay to have multiple rules in the text; if so, - * each rule should be terminated with a newline. - * @return 0 on success - */ -GIT_EXTERN(int) git_ignore_add_rule( - git_repository *repo, - const char *rules); - -/** - * Clear ignore rules that were explicitly added. - * - * Resets to the default internal ignore rules. This will not turn off - * rules in .gitignore files that actually exist in the filesystem. - * - * The default internal ignores ignore ".", ".." and ".git" entries. - * - * @param repo The repository to remove ignore rules from. - * @return 0 on success - */ -GIT_EXTERN(int) git_ignore_clear_internal_rules( - git_repository *repo); - -/** - * Test if the ignore rules apply to a given path. - * - * This function checks the ignore rules to see if they would apply to the - * given file. This indicates if the file would be ignored regardless of - * whether the file is already in the index or committed to the repository. - * - * One way to think of this is if you were to do "git add ." on the - * directory containing the file, would it be added or not? - * - * @param ignored boolean returning 0 if the file is not ignored, 1 if it is - * @param repo a repository object - * @param path the file to check ignores for, relative to the repo's workdir. - * @return 0 if ignore rules could be processed for the file (regardless - * of whether it exists or not), or an error < 0 if they could not. - */ -GIT_EXTERN(int) git_ignore_path_is_ignored( - int *ignored, - git_repository *repo, - const char *path); - -GIT_END_DECL - -#endif diff --git a/git2/include/git2/index.h b/git2/include/git2/index.h deleted file mode 100644 index 2df5103fd..000000000 --- a/git2/include/git2/index.h +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_index_h__ -#define INCLUDE_git_index_h__ - -#include "common.h" -#include "indexer.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/index.h - * @brief Git index parsing and manipulation routines - * @defgroup git_index Git index parsing and manipulation routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -#define GIT_IDXENTRY_NAMEMASK (0x0fff) -#define GIT_IDXENTRY_STAGEMASK (0x3000) -#define GIT_IDXENTRY_EXTENDED (0x4000) -#define GIT_IDXENTRY_VALID (0x8000) -#define GIT_IDXENTRY_STAGESHIFT 12 - -/* - * Flags are divided into two parts: in-memory flags and - * on-disk ones. Flags in GIT_IDXENTRY_EXTENDED_FLAGS - * will get saved on-disk. - * - * In-memory only flags: - */ -#define GIT_IDXENTRY_UPDATE (1 << 0) -#define GIT_IDXENTRY_REMOVE (1 << 1) -#define GIT_IDXENTRY_UPTODATE (1 << 2) -#define GIT_IDXENTRY_ADDED (1 << 3) - -#define GIT_IDXENTRY_HASHED (1 << 4) -#define GIT_IDXENTRY_UNHASHED (1 << 5) -#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ -#define GIT_IDXENTRY_CONFLICTED (1 << 7) - -#define GIT_IDXENTRY_UNPACKED (1 << 8) -#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9) - -/* - * Extended on-disk flags: - */ -#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) -#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) -/* GIT_IDXENTRY_EXTENDED2 is for future extension */ -#define GIT_IDXENTRY_EXTENDED2 (1 << 15) - -#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) - -/** Time used in a git index entry */ -typedef struct { - git_time_t seconds; - /* nsec should not be stored as time_t compatible */ - unsigned int nanoseconds; -} git_index_time; - -/** Memory representation of a file entry in the index. */ -typedef struct git_index_entry { - git_index_time ctime; - git_index_time mtime; - - unsigned int dev; - unsigned int ino; - unsigned int mode; - unsigned int uid; - unsigned int gid; - git_off_t file_size; - - git_oid oid; - - unsigned short flags; - unsigned short flags_extended; - - char *path; -} git_index_entry; - -/** Representation of a resolve undo entry in the index. */ -typedef struct git_index_reuc_entry { - unsigned int mode[3]; - git_oid oid[3]; - char *path; -} git_index_reuc_entry; - -/** Capabilities of system that affect index actions. */ -enum { - GIT_INDEXCAP_IGNORE_CASE = 1, - GIT_INDEXCAP_NO_FILEMODE = 2, - GIT_INDEXCAP_NO_SYMLINKS = 4, - GIT_INDEXCAP_FROM_OWNER = ~0u -}; - -/** @name Index File Functions - * - * These functions work on the index file itself. - */ -/**@{*/ - -/** - * Create a new bare Git index object as a memory representation - * of the Git index file in 'index_path', without a repository - * to back it. - * - * Since there is no ODB or working directory behind this index, - * any Index methods which rely on these (e.g. index_add) will - * fail with the GIT_EBAREINDEX error code. - * - * If you need to access the index of an actual repository, - * use the `git_repository_index` wrapper. - * - * The index must be freed once it's no longer in use. - * - * @param out the pointer for the new index - * @param index_path the path to the index file in disk - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_open(git_index **out, const char *index_path); - -/** - * Create an in-memory index object. - * - * This index object cannot be read/written to the filesystem, - * but may be used to perform in-memory index operations. - * - * The index must be freed once it's no longer in use. - * - * @param out the pointer for the new index - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_new(git_index **out); - -/** - * Free an existing index object. - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_free(git_index *index); - -/** - * Get the repository this index relates to - * - * @param index The index - * @return A pointer to the repository - */ -GIT_EXTERN(git_repository *) git_index_owner(const git_index *index); - -/** - * Read index capabilities flags. - * - * @param index An existing index object - * @return A combination of GIT_INDEXCAP values - */ -GIT_EXTERN(unsigned int) git_index_caps(const git_index *index); - -/** - * Set index capabilities flags. - * - * If you pass `GIT_INDEXCAP_FROM_OWNER` for the caps, then the - * capabilities will be read from the config of the owner object, - * looking at `core.ignorecase`, `core.filemode`, `core.symlinks`. - * - * @param index An existing index object - * @param caps A combination of GIT_INDEXCAP values - * @return 0 on success, -1 on failure - */ -GIT_EXTERN(int) git_index_set_caps(git_index *index, unsigned int caps); - -/** - * Update the contents of an existing index object in memory - * by reading from the hard disk. - * - * @param index an existing index object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_read(git_index *index); - -/** - * Write an existing index object from memory back to disk - * using an atomic file lock. - * - * @param index an existing index object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_write(git_index *index); - -/** - * Read a tree into the index file with stats - * - * The current index contents will be replaced by the specified tree. - * - * @param index an existing index object - * @param tree tree to read - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_read_tree(git_index *index, const git_tree *tree); - -/** - * Write the index as a tree - * - * This method will scan the index and write a representation - * of its current state back to disk; it recursively creates - * tree objects for each of the subtrees stored in the index, - * but only returns the OID of the root tree. This is the OID - * that can be used e.g. to create a commit. - * - * The index instance cannot be bare, and needs to be associated - * to an existing repository. - * - * The index must not contain any file in conflict. - * - * @param out Pointer where to store the OID of the written tree - * @param index Index to write - * @return 0 on success, GIT_EUNMERGED when the index is not clean - * or an error code - */ -GIT_EXTERN(int) git_index_write_tree(git_oid *out, git_index *index); - -/** - * Write the index as a tree to the given repository - * - * This method will do the same as `git_index_write_tree`, but - * letting the user choose the repository where the tree will - * be written. - * - * The index must not contain any file in conflict. - * - * @param out Pointer where to store OID of the the written tree - * @param index Index to write - * @param repo Repository where to write the tree - * @return 0 on success, GIT_EUNMERGED when the index is not clean - * or an error code - */ -GIT_EXTERN(int) git_index_write_tree_to(git_oid *out, git_index *index, git_repository *repo); - -/**@}*/ - -/** @name Raw Index Entry Functions - * - * These functions work on index entries, and allow for raw manipulation - * of the entries. - */ -/**@{*/ - -/* Index entry manipulation */ - -/** - * Get the count of entries currently in the index - * - * @param index an existing index object - * @return integer of count of current entries - */ -GIT_EXTERN(size_t) git_index_entrycount(const git_index *index); - -/** - * Clear the contents (all the entries) of an index object. - * This clears the index object in memory; changes must be manually - * written to disk for them to take effect. - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_clear(git_index *index); - -/** - * Get a pointer to one of the entries in the index - * - * The values of this entry can be modified (except the path) - * and the changes will be written back to disk on the next - * write() call. - * - * The entry should not be freed by the caller. - * - * @param index an existing index object - * @param n the position of the entry - * @return a pointer to the entry; NULL if out of bounds - */ -GIT_EXTERN(const git_index_entry *) git_index_get_byindex( - git_index *index, size_t n); - -/** - * Get a pointer to one of the entries in the index - * - * The values of this entry can be modified (except the path) - * and the changes will be written back to disk on the next - * write() call. - * - * The entry should not be freed by the caller. - * - * @param index an existing index object - * @param path path to search - * @param stage stage to search - * @return a pointer to the entry; NULL if it was not found - */ -GIT_EXTERN(const git_index_entry *) git_index_get_bypath( - git_index *index, const char *path, int stage); - -/** - * Remove an entry from the index - * - * @param index an existing index object - * @param path path to search - * @param stage stage to search - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_remove(git_index *index, const char *path, int stage); - -/** - * Remove all entries from the index under a given directory - * - * @param index an existing index object - * @param dir container directory path - * @param stage stage to search - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_remove_directory( - git_index *index, const char *dir, int stage); - -/** - * Add or update an index entry from an in-memory struct - * - * If a previous index entry exists that has the same path and stage - * as the given 'source_entry', it will be replaced. Otherwise, the - * 'source_entry' will be added. - * - * A full copy (including the 'path' string) of the given - * 'source_entry' will be inserted on the index. - * - * @param index an existing index object - * @param source_entry new entry object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_add(git_index *index, const git_index_entry *source_entry); - -/** - * Return the stage number from a git index entry - * - * This entry is calculated from the entry's flag - * attribute like this: - * - * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT - * - * @param entry The entry - * @returns the stage number - */ -GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry); - -/**@}*/ - -/** @name Workdir Index Entry Functions - * - * These functions work on index entries specifically in the working - * directory (ie, stage 0). - */ -/**@{*/ - -/** - * Add or update an index entry from a file in disk - * - * The file `path` must be relative to the repository's - * working folder and must be readable. - * - * This method will fail in bare index instances. - * - * This forces the file to be added to the index, not looking - * at gitignore rules. Those rules can be evaluated through - * the git_status APIs (in status.h) before calling this. - * - * If this file currently is the result of a merge conflict, this - * file will no longer be marked as conflicting. The data about - * the conflict will be moved to the "resolve undo" (REUC) section. - * - * @param index an existing index object - * @param path filename to add - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_add_from_workdir(git_index *index, const char *path); - -/** - * Find the first index of any entries which point to given - * path in the Git index. - * - * @param index an existing index object - * @param path path to search - * @return an index >= 0 if found, -1 otherwise - */ -GIT_EXTERN(int) git_index_find(git_index *index, const char *path); - -/**@}*/ - -/** @name Conflict Index Entry Functions - * - * These functions work on conflict index entries specifically (ie, stages 1-3) - */ -/**@{*/ - -/** - * Add or update index entries to represent a conflict - * - * The entries are the entries from the tree included in the merge. Any - * entry may be null to indicate that that file was not present in the - * trees during the merge. For example, ancestor_entry may be NULL to - * indicate that a file was added in both branches and must be resolved. - * - * @param index an existing index object - * @param ancestor_entry the entry data for the ancestor of the conflict - * @param our_entry the entry data for our side of the merge conflict - * @param their_entry the entry data for their side of the merge conflict - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_conflict_add( - git_index *index, - const git_index_entry *ancestor_entry, - const git_index_entry *our_entry, - const git_index_entry *their_entry); - -/** - * Get the index entries that represent a conflict of a single file. - * - * The values of this entry can be modified (except the paths) - * and the changes will be written back to disk on the next - * write() call. - * - * @param ancestor_out Pointer to store the ancestor entry - * @param our_out Pointer to store the our entry - * @param their_out Pointer to store the their entry - * @param index an existing index object - * @param path path to search - */ -GIT_EXTERN(int) git_index_conflict_get(git_index_entry **ancestor_out, git_index_entry **our_out, git_index_entry **their_out, git_index *index, const char *path); - -/** - * Removes the index entries that represent a conflict of a single file. - * - * @param index an existing index object - * @param path to search - */ -GIT_EXTERN(int) git_index_conflict_remove(git_index *index, const char *path); - -/** - * Remove all conflicts in the index (entries with a stage greater than 0.) - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_conflict_cleanup(git_index *index); - -/** - * Determine if the index contains entries representing file conflicts. - * - * @return 1 if at least one conflict is found, 0 otherwise. - */ -GIT_EXTERN(int) git_index_has_conflicts(const git_index *index); - -/**@}*/ - -/** @name Resolve Undo (REUC) index entry manipulation. - * - * These functions work on the Resolve Undo index extension and contains - * data about the original files that led to a merge conflict. - */ -/**@{*/ - -/** - * Get the count of resolve undo entries currently in the index. - * - * @param index an existing index object - * @return integer of count of current resolve undo entries - */ -GIT_EXTERN(unsigned int) git_index_reuc_entrycount(git_index *index); - -/** - * Finds the resolve undo entry that points to the given path in the Git - * index. - * - * @param index an existing index object - * @param path path to search - * @return an index >= 0 if found, -1 otherwise - */ -GIT_EXTERN(int) git_index_reuc_find(git_index *index, const char *path); - -/** - * Get a resolve undo entry from the index. - * - * The returned entry is read-only and should not be modified - * or freed by the caller. - * - * @param index an existing index object - * @param path path to search - * @return the resolve undo entry; NULL if not found - */ -GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_bypath(git_index *index, const char *path); - -/** - * Get a resolve undo entry from the index. - * - * The returned entry is read-only and should not be modified - * or freed by the caller. - * - * @param index an existing index object - * @param n the position of the entry - * @return a pointer to the resolve undo entry; NULL if out of bounds - */ -GIT_EXTERN(const git_index_reuc_entry *) git_index_reuc_get_byindex(git_index *index, size_t n); - -/** - * Adds a resolve undo entry for a file based on the given parameters. - * - * The resolve undo entry contains the OIDs of files that were involved - * in a merge conflict after the conflict has been resolved. This allows - * conflicts to be re-resolved later. - * - * If there exists a resolve undo entry for the given path in the index, - * it will be removed. - * - * This method will fail in bare index instances. - * - * @param index an existing index object - * @param path filename to add - * @param ancestor_mode mode of the ancestor file - * @param ancestor_id oid of the ancestor file - * @param our_mode mode of our file - * @param our_id oid of our file - * @param their_mode mode of their file - * @param their_id oid of their file - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_reuc_add(git_index *index, const char *path, - int ancestor_mode, git_oid *ancestor_id, - int our_mode, git_oid *our_id, - int their_mode, git_oid *their_id); - -/** - * Remove an resolve undo entry from the index - * - * @param index an existing index object - * @param n position of the resolve undo entry to remove - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_reuc_remove(git_index *index, size_t n); - -/**@}*/ - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/indexer.h b/git2/include/git2/indexer.h deleted file mode 100644 index c428d43a8..000000000 --- a/git2/include/git2/indexer.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef _INCLUDE_git_indexer_h__ -#define _INCLUDE_git_indexer_h__ - -#include "common.h" -#include "oid.h" - -GIT_BEGIN_DECL - -/** - * This is passed as the first argument to the callback to allow the - * user to see the progress. - */ -typedef struct git_transfer_progress { - unsigned int total_objects; - unsigned int indexed_objects; - unsigned int received_objects; - size_t received_bytes; -} git_transfer_progress; - - -/** - * Type for progress callbacks during indexing - */ -typedef void (*git_transfer_progress_callback)(const git_transfer_progress *stats, void *payload); - -typedef struct git_indexer git_indexer; -typedef struct git_indexer_stream git_indexer_stream; - -/** - * Create a new streaming indexer instance - * - * @param out where to store the indexer instance - * @param path to the directory where the packfile should be stored - * @param progress_cb function to call with progress information - * @param progress_payload payload for the progress callback - */ -GIT_EXTERN(int) git_indexer_stream_new( - git_indexer_stream **out, - const char *path, - git_transfer_progress_callback progress_cb, - void *progress_cb_payload); - -/** - * Add data to the indexer - * - * @param idx the indexer - * @param data the data to add - * @param size the size of the data in bytes - * @param stats stat storage - */ -GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_transfer_progress *stats); - -/** - * Finalize the pack and index - * - * Resolve any pending deltas and write out the index file - * - * @param idx the indexer - */ -GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_transfer_progress *stats); - -/** - * Get the packfile's hash - * - * A packfile's name is derived from the sorted hashing of all object - * names. This is only correct after the index has been finalized. - * - * @param idx the indexer instance - */ -GIT_EXTERN(const git_oid *) git_indexer_stream_hash(const git_indexer_stream *idx); - -/** - * Free the indexer and its resources - * - * @param idx the indexer to free - */ -GIT_EXTERN(void) git_indexer_stream_free(git_indexer_stream *idx); - -/** - * Create a new indexer instance - * - * @param out where to store the indexer instance - * @param packname the absolute filename of the packfile to index - */ -GIT_EXTERN(int) git_indexer_new(git_indexer **out, const char *packname); - -/** - * Iterate over the objects in the packfile and extract the information - * - * Indexing a packfile can be very expensive so this function is - * expected to be run in a worker thread and the stats used to provide - * feedback the user. - * - * @param idx the indexer instance - * @param stats storage for the running state - */ -GIT_EXTERN(int) git_indexer_run(git_indexer *idx, git_transfer_progress *stats); - -/** - * Write the index file to disk. - * - * The file will be stored as pack-$hash.idx in the same directory as - * the packfile. - * - * @param idx the indexer instance - */ -GIT_EXTERN(int) git_indexer_write(git_indexer *idx); - -/** - * Get the packfile's hash - * - * A packfile's name is derived from the sorted hashing of all object - * names. This is only correct after the index has been written to disk. - * - * @param idx the indexer instance - */ -GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx); - -/** - * Free the indexer and its resources - * - * @param idx the indexer to free - */ -GIT_EXTERN(void) git_indexer_free(git_indexer *idx); - -GIT_END_DECL - -#endif diff --git a/git2/include/git2/merge.h b/git2/include/git2/merge.h deleted file mode 100644 index f4c5d9881..000000000 --- a/git2/include/git2/merge.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_merge_h__ -#define INCLUDE_git_merge_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/merge.h - * @brief Git merge-base routines - * @defgroup git_revwalk Git merge-base routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Find a merge base between two commits - * - * @param out the OID of a merge base between 'one' and 'two' - * @param repo the repository where the commits exist - * @param one one of the commits - * @param two the other commit - * @return Zero on success; GIT_ENOTFOUND or -1 on failure. - */ -GIT_EXTERN(int) git_merge_base( - git_oid *out, - git_repository *repo, - const git_oid *one, - const git_oid *two); - -/** - * Find a merge base given a list of commits - * - * @param out the OID of a merge base considering all the commits - * @param repo the repository where the commits exist - * @param input_array oids of the commits - * @param length The number of commits in the provided `input_array` - * @return Zero on success; GIT_ENOTFOUND or -1 on failure. - */ -GIT_EXTERN(int) git_merge_base_many( - git_oid *out, - git_repository *repo, - const git_oid input_array[], - size_t length); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/message.h b/git2/include/git2/message.h deleted file mode 100644 index 395c88690..000000000 --- a/git2/include/git2/message.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_message_h__ -#define INCLUDE_git_message_h__ - -#include "common.h" - -/** - * @file git2/message.h - * @brief Git message management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Clean up message from excess whitespace and make sure that the last line - * ends with a '\n'. - * - * Optionally, can remove lines starting with a "#". - * - * @param out The user-allocated buffer which will be filled with the - * cleaned up message. Pass NULL if you just want to get the needed - * size of the prettified message as the output value. - * - * @param out_size Size of the `out` buffer in bytes. - * - * @param message The message to be prettified. - * - * @param strip_comments Non-zero to remove lines starting with "#", 0 to - * leave them in. - * - * @return -1 on error, else number of characters in prettified message - * including the trailing NUL byte - */ -GIT_EXTERN(int) git_message_prettify( - char *out, - size_t out_size, - const char *message, - int strip_comments); - -/** @} */ -GIT_END_DECL - -#endif /* INCLUDE_git_message_h__ */ diff --git a/git2/include/git2/net.h b/git2/include/git2/net.h deleted file mode 100644 index 6e3525f5d..000000000 --- a/git2/include/git2/net.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_net_h__ -#define INCLUDE_git_net_h__ - -#include "common.h" -#include "oid.h" -#include "types.h" - -/** - * @file git2/net.h - * @brief Git networking declarations - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -#define GIT_DEFAULT_PORT "9418" - -/* - * We need this because we need to know whether we should call - * git-upload-pack or git-receive-pack on the remote end when get_refs - * gets called. - */ - -typedef enum { - GIT_DIRECTION_FETCH = 0, - GIT_DIRECTION_PUSH = 1 -} git_direction; - - -/** - * Remote head description, given out on `ls` calls. - */ -struct git_remote_head { - int local:1; /* available locally */ - git_oid oid; - git_oid loid; - char *name; -}; - -/** - * Callback for listing the remote heads - */ -typedef int (*git_headlist_cb)(git_remote_head *rhead, void *payload); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/notes.h b/git2/include/git2/notes.h deleted file mode 100644 index c51d3732a..000000000 --- a/git2/include/git2/notes.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_note_h__ -#define INCLUDE_git_note_h__ - -#include "oid.h" - -/** - * @file git2/notes.h - * @brief Git notes management routines - * @defgroup git_note Git notes management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Callback for git_note_foreach. - * - * Receives: - * - blob_id: Oid of the blob containing the message - * - annotated_object_id: Oid of the git object being annotated - * - payload: Payload data passed to `git_note_foreach` - */ -typedef int (*git_note_foreach_cb)( - const git_oid *blob_id, const git_oid *annotated_object_id, void *payload); - -/** - * Read the note for an object - * - * The note must be freed manually by the user. - * - * @param out pointer to the read note; NULL in case of error - * @param repo repository where to look up the note - * @param notes_ref canonical name of the reference to use (optional); defaults to - * "refs/notes/commits" - * @param oid OID of the git object to read the note from - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_read( - git_note **out, - git_repository *repo, - const char *notes_ref, - const git_oid *oid); - -/** - * Get the note message - * - * @param note - * @return the note message - */ -GIT_EXTERN(const char *) git_note_message(const git_note *note); - - -/** - * Get the note object OID - * - * @param note - * @return the note object OID - */ -GIT_EXTERN(const git_oid *) git_note_oid(const git_note *note); - -/** - * Add a note for an object - * - * @param out pointer to store the OID (optional); NULL in case of error - * @param repo repository where to store the note - * @param author signature of the notes commit author - * @param committer signature of the notes commit committer - * @param notes_ref canonical name of the reference to use (optional); - * defaults to "refs/notes/commits" - * @param oid OID of the git object to decorate - * @param note Content of the note to add for object oid - * @param force Overwrite existing note - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_create( - git_oid *out, - git_repository *repo, - const git_signature *author, - const git_signature *committer, - const char *notes_ref, - const git_oid *oid, - const char *note, - int force); - - -/** - * Remove the note for an object - * - * @param repo repository where the note lives - * @param notes_ref canonical name of the reference to use (optional); - * defaults to "refs/notes/commits" - * @param author signature of the notes commit author - * @param committer signature of the notes commit committer - * @param oid OID of the git object to remove the note from - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_remove( - git_repository *repo, - const char *notes_ref, - const git_signature *author, - const git_signature *committer, - const git_oid *oid); - -/** - * Free a git_note object - * - * @param note git_note object - */ -GIT_EXTERN(void) git_note_free(git_note *note); - -/** - * Get the default notes reference for a repository - * - * @param out Pointer to the default notes reference - * @param repo The Git repository - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo); - -/** - * Loop over all the notes within a specified namespace - * and issue a callback for each one. - * - * @param repo Repository where to find the notes. - * - * @param notes_ref Reference to read from (optional); defaults to - * "refs/notes/commits". - * - * @param note_cb Callback to invoke per found annotation. Return non-zero - * to stop looping. - * - * @param payload Extra parameter to callback function. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_note_foreach( - git_repository *repo, - const char *notes_ref, - git_note_foreach_cb note_cb, - void *payload); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/object.h b/git2/include/git2/object.h deleted file mode 100644 index e029f0125..000000000 --- a/git2/include/git2/object.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_object_h__ -#define INCLUDE_git_object_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/object.h - * @brief Git revision object management routines - * @defgroup git_object Git revision object management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a reference to one of the objects in a repository. - * - * The generated reference is owned by the repository and - * should be closed with the `git_object_free` method - * instead of free'd manually. - * - * The 'type' parameter must match the type of the object - * in the odb; the method will fail otherwise. - * The special value 'GIT_OBJ_ANY' may be passed to let - * the method guess the object's type. - * - * @param object pointer to the looked-up object - * @param repo the repository to look up the object - * @param id the unique identifier for the object - * @param type the type of the object - * @return a reference to the object - */ -GIT_EXTERN(int) git_object_lookup( - git_object **object, - git_repository *repo, - const git_oid *id, - git_otype type); - -/** - * Lookup a reference to one of the objects in a repository, - * given a prefix of its identifier (short id). - * - * The object obtained will be so that its identifier - * matches the first 'len' hexadecimal characters - * (packets of 4 bits) of the given 'id'. - * 'len' must be at least GIT_OID_MINPREFIXLEN, and - * long enough to identify a unique object matching - * the prefix; otherwise the method will fail. - * - * The generated reference is owned by the repository and - * should be closed with the `git_object_free` method - * instead of free'd manually. - * - * The 'type' parameter must match the type of the object - * in the odb; the method will fail otherwise. - * The special value 'GIT_OBJ_ANY' may be passed to let - * the method guess the object's type. - * - * @param object_out pointer where to store the looked-up object - * @param repo the repository to look up the object - * @param id a short identifier for the object - * @param len the length of the short identifier - * @param type the type of the object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_object_lookup_prefix( - git_object **object_out, - git_repository *repo, - const git_oid *id, - size_t len, - git_otype type); - -/** - * Get the id (SHA1) of a repository object - * - * @param obj the repository object - * @return the SHA1 id - */ -GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj); - -/** - * Get the object type of an object - * - * @param obj the repository object - * @return the object's type - */ -GIT_EXTERN(git_otype) git_object_type(const git_object *obj); - -/** - * Get the repository that owns this object - * - * Freeing or calling `git_repository_close` on the - * returned pointer will invalidate the actual object. - * - * Any other operation may be run on the repository without - * affecting the object. - * - * @param obj the object - * @return the repository who owns this object - */ -GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj); - -/** - * Close an open object - * - * This method instructs the library to close an existing - * object; note that git_objects are owned and cached by the repository - * so the object may or may not be freed after this library call, - * depending on how aggressive is the caching mechanism used - * by the repository. - * - * IMPORTANT: - * It *is* necessary to call this method when you stop using - * an object. Failure to do so will cause a memory leak. - * - * @param object the object to close - */ -GIT_EXTERN(void) git_object_free(git_object *object); - -/** - * Convert an object type to it's string representation. - * - * The result is a pointer to a string in static memory and - * should not be free()'ed. - * - * @param type object type to convert. - * @return the corresponding string representation. - */ -GIT_EXTERN(const char *) git_object_type2string(git_otype type); - -/** - * Convert a string object type representation to it's git_otype. - * - * @param str the string to convert. - * @return the corresponding git_otype. - */ -GIT_EXTERN(git_otype) git_object_string2type(const char *str); - -/** - * Determine if the given git_otype is a valid loose object type. - * - * @param type object type to test. - * @return true if the type represents a valid loose object type, - * false otherwise. - */ -GIT_EXTERN(int) git_object_typeisloose(git_otype type); - -/** - * Get the size in bytes for the structure which - * acts as an in-memory representation of any given - * object type. - * - * For all the core types, this would the equivalent - * of calling `sizeof(git_commit)` if the core types - * were not opaque on the external API. - * - * @param type object type to get its size - * @return size in bytes of the object - */ -GIT_EXTERN(size_t) git_object__size(git_otype type); - -/** - * Recursively peel an object until an object of the specified type is met. - * - * The retrieved `peeled` object is owned by the repository and should be - * closed with the `git_object_free` method. - * - * If you pass `GIT_OBJ_ANY` as the target type, then the object will be - * peeled until the type changes (e.g. a tag will be chased until the - * referenced object is no longer a tag). - * - * @param peeled Pointer to the peeled git_object - * @param object The object to be processed - * @param target_type The type of the requested object (GIT_OBJ_COMMIT, - * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY). - * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code - */ -GIT_EXTERN(int) git_object_peel( - git_object **peeled, - const git_object *object, - git_otype target_type); - -/** @} */ -GIT_END_DECL - -#endif diff --git a/git2/include/git2/odb.h b/git2/include/git2/odb.h deleted file mode 100644 index f39e7b541..000000000 --- a/git2/include/git2/odb.h +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_odb_h__ -#define INCLUDE_git_odb_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "odb_backend.h" -#include "indexer.h" - -/** - * @file git2/odb.h - * @brief Git object database routines - * @defgroup git_odb Git object database routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new object database with no backends. - * - * Before the ODB can be used for read/writing, a custom database - * backend must be manually added using `git_odb_add_backend()` - * - * @param out location to store the database pointer, if opened. - * Set to NULL if the open failed. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_new(git_odb **out); - -/** - * Create a new object database and automatically add - * the two default backends: - * - * - git_odb_backend_loose: read and write loose object files - * from disk, assuming `objects_dir` as the Objects folder - * - * - git_odb_backend_pack: read objects from packfiles, - * assuming `objects_dir` as the Objects folder which - * contains a 'pack/' folder with the corresponding data - * - * @param out location to store the database pointer, if opened. - * Set to NULL if the open failed. - * @param objects_dir path of the backends' "objects" directory. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); - -/** - * Add a custom backend to an existing Object DB - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Read for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); - -/** - * Add a custom backend to an existing Object DB; this - * backend will work as an alternate. - * - * Alternate backends are always checked for objects *after* - * all the main backends have been exhausted. - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Writing is disabled on alternate backends. - * - * Read for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); - -/** - * Add an on-disk alternate to an existing Object DB. - * - * Note that the added path must point to an `objects`, not - * to a full repository, to use it as an alternate store. - * - * Alternate backends are always checked for objects *after* - * all the main backends have been exhausted. - * - * Writing is disabled on alternate backends. - * - * @param odb database to add the backend to - * @param path path to the objects folder for the alternate - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_disk_alternate(git_odb *odb, const char *path); - -/** - * Close an open object database. - * - * @param db database pointer to close. If NULL no action is taken. - */ -GIT_EXTERN(void) git_odb_free(git_odb *db); - -/** - * Read an object from the database. - * - * This method queries all available ODB backends - * trying to read the given OID. - * - * The returned object is reference counted and - * internally cached, so it should be closed - * by the user once it's no longer in use. - * - * @param out pointer where to store the read object - * @param db database to search for the object in. - * @param id identity of the object to read. - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. - */ -GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id); - -/** - * Read an object from the database, given a prefix - * of its identifier. - * - * This method queries all available ODB backends - * trying to match the 'len' first hexadecimal - * characters of the 'short_id'. - * The remaining (GIT_OID_HEXSZ-len)*4 bits of - * 'short_id' must be 0s. - * 'len' must be at least GIT_OID_MINPREFIXLEN, - * and the prefix must be long enough to identify - * a unique object in all the backends; the - * method will fail otherwise. - * - * The returned object is reference counted and - * internally cached, so it should be closed - * by the user once it's no longer in use. - * - * @param out pointer where to store the read object - * @param db database to search for the object in. - * @param short_id a prefix of the id of the object to read. - * @param len the length of the prefix - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. - * - GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix) - */ -GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len); - -/** - * Read the header of an object from the database, without - * reading its full contents. - * - * The header includes the length and the type of an object. - * - * Note that most backends do not support reading only the header - * of an object, so the whole object will be read and then the - * header will be returned. - * - * @param len_out pointer where to store the length - * @param type_out pointer where to store the type - * @param db database to search for the object in. - * @param id identity of the object to read. - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. - */ -GIT_EXTERN(int) git_odb_read_header(size_t *len_out, git_otype *type_out, git_odb *db, const git_oid *id); - -/** - * Determine if the given object can be found in the object database. - * - * @param db database to be searched for the given object. - * @param id the object to search for. - * @return - * - 1, if the object was found - * - 0, otherwise - */ -GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id); - -/** - * List all objects available in the database - * - * The callback will be called for each object available in the - * database. Note that the objects are likely to be returned in the index - * order, which would make accessing the objects in that order inefficient. - * Return a non-zero value from the callback to stop looping. - * - * @param db database to use - * @param cb the callback to call for each object - * @param payload data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload); - -/** - * Write an object directly into the ODB - * - * This method writes a full object straight into the ODB. - * For most cases, it is preferred to write objects through a write - * stream, which is both faster and less memory intensive, specially - * for big objects. - * - * This method is provided for compatibility with custom backends - * which are not able to support streaming writes - * - * @param out pointer to store the OID result of the write - * @param odb object database where to store the object - * @param data buffer with the data to store - * @param len size of the buffer - * @param type type of the data to store - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size_t len, git_otype type); - -/** - * Open a stream to write an object into the ODB - * - * The type and final length of the object must be specified - * when opening the stream. - * - * The returned stream will be of type `GIT_STREAM_WRONLY` and - * will have the following methods: - * - * - stream->write: write `n` bytes into the stream - * - stream->finalize_write: close the stream and store the object in - * the odb - * - stream->free: free the stream - * - * The streaming write won't be effective until `stream->finalize_write` - * is called and returns without an error - * - * The stream must always be free'd or will leak memory. - * - * @see git_odb_stream - * - * @param out pointer where to store the stream - * @param db object database where the stream will write - * @param size final size of the object that will be written - * @param type type of the object that will be written - * @return 0 if the stream was created; error code otherwise - */ -GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, size_t size, git_otype type); - -/** - * Open a stream to read an object from the ODB - * - * Note that most backends do *not* support streaming reads - * because they store their objects as compressed/delta'ed blobs. - * - * It's recommended to use `git_odb_read` instead, which is - * assured to work on all backends. - * - * The returned stream will be of type `GIT_STREAM_RDONLY` and - * will have the following methods: - * - * - stream->read: read `n` bytes from the stream - * - stream->free: free the stream - * - * The stream must always be free'd or will leak memory. - * - * @see git_odb_stream - * - * @param out pointer where to store the stream - * @param db object database where the stream will read from - * @param oid oid of the object the stream will read from - * @return 0 if the stream was created; error code otherwise - */ -GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **out, git_odb *db, const git_oid *oid); - -/** - * Open a stream for writing a pack file to the ODB. - * - * If the ODB layer understands pack files, then the given - * packfile will likely be streamed directly to disk (and a - * corresponding index created). If the ODB layer does not - * understand pack files, the objects will be stored in whatever - * format the ODB layer uses. - * - * @see git_odb_writepack - * - * @param out pointer to the writepack functions - * @param db object database where the stream will read from - * @param progress_cb function to call with progress information. - * Be aware that this is called inline with network and indexing operations, - * so performance may be affected. - * @param progress_payload payload for the progress callback - */ -GIT_EXTERN(int) git_odb_write_pack( - git_odb_writepack **out, - git_odb *db, - git_transfer_progress_callback progress_cb, - void *progress_payload); - -/** - * Determine the object-ID (sha1 hash) of a data buffer - * - * The resulting SHA-1 OID will be the identifier for the data - * buffer as if the data buffer it were to written to the ODB. - * - * @param out the resulting object-ID. - * @param data data to hash - * @param len size of the data - * @param type of the data to hash - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_hash(git_oid *out, const void *data, size_t len, git_otype type); - -/** - * Read a file from disk and fill a git_oid with the object id - * that the file would have if it were written to the Object - * Database as an object of the given type (w/o applying filters). - * Similar functionality to git.git's `git hash-object` without - * the `-w` flag, however, with the --no-filters flag. - * If you need filters, see git_repository_hashfile. - * - * @param out oid structure the result is written into. - * @param path file to read and determine object id for - * @param type the type of the object that will be hashed - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_otype type); - -/** - * Close an ODB object - * - * This method must always be called once a `git_odb_object` is no - * longer needed, otherwise memory will leak. - * - * @param object object to close - */ -GIT_EXTERN(void) git_odb_object_free(git_odb_object *object); - -/** - * Return the OID of an ODB object - * - * This is the OID from which the object was read from - * - * @param object the object - * @return a pointer to the OID - */ -GIT_EXTERN(const git_oid *) git_odb_object_id(git_odb_object *object); - -/** - * Return the data of an ODB object - * - * This is the uncompressed, raw data as read from the ODB, - * without the leading header. - * - * This pointer is owned by the object and shall not be free'd. - * - * @param object the object - * @return a pointer to the data - */ -GIT_EXTERN(const void *) git_odb_object_data(git_odb_object *object); - -/** - * Return the size of an ODB object - * - * This is the real size of the `data` buffer, not the - * actual size of the object. - * - * @param object the object - * @return the size - */ -GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object); - -/** - * Return the type of an ODB object - * - * @param object the object - * @return the type - */ -GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/odb_backend.h b/git2/include/git2/odb_backend.h deleted file mode 100644 index 029c61b9f..000000000 --- a/git2/include/git2/odb_backend.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_odb_backend_h__ -#define INCLUDE_git_odb_backend_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "indexer.h" - -/** - * @file git2/backend.h - * @brief Git custom backend functions - * @defgroup git_backend Git custom backend API - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -struct git_odb_stream; -struct git_odb_writepack; - -/** - * Function type for callbacks from git_odb_foreach. - */ -typedef int (*git_odb_foreach_cb)(const git_oid *id, void *payload); - -/** - * An instance for a custom backend - */ -struct git_odb_backend { - unsigned int version; - git_odb *odb; - - /* read and read_prefix each return to libgit2 a buffer which - * will be freed later. The buffer should be allocated using - * the function git_odb_backend_malloc to ensure that it can - * be safely freed later. */ - int (* read)( - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* To find a unique object given a prefix - * of its oid. - * The oid given must be so that the - * remaining (GIT_OID_HEXSZ - len)*4 bits - * are 0s. - */ - int (* read_prefix)( - git_oid *, - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *, - size_t); - - int (* read_header)( - size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* The writer may assume that the object - * has already been hashed and is passed - * in the first parameter. - */ - int (* write)( - git_oid *, - struct git_odb_backend *, - const void *, - size_t, - git_otype); - - int (* writestream)( - struct git_odb_stream **, - struct git_odb_backend *, - size_t, - git_otype); - - int (* readstream)( - struct git_odb_stream **, - struct git_odb_backend *, - const git_oid *); - - int (* exists)( - struct git_odb_backend *, - const git_oid *); - - int (* foreach)( - struct git_odb_backend *, - git_odb_foreach_cb cb, - void *payload); - - int (* writepack)( - struct git_odb_writepack **, - struct git_odb_backend *, - git_transfer_progress_callback progress_cb, - void *progress_payload); - - void (* free)(struct git_odb_backend *); -}; - -#define GIT_ODB_BACKEND_VERSION 1 -#define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION} - -/** Streaming mode */ -enum { - GIT_STREAM_RDONLY = (1 << 1), - GIT_STREAM_WRONLY = (1 << 2), - GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY), -}; - -/** A stream to read/write from a backend */ -struct git_odb_stream { - struct git_odb_backend *backend; - unsigned int mode; - - int (*read)(struct git_odb_stream *stream, char *buffer, size_t len); - int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len); - int (*finalize_write)(git_oid *oid_p, struct git_odb_stream *stream); - void (*free)(struct git_odb_stream *stream); -}; - -/** A stream to write a pack file to the ODB */ -struct git_odb_writepack { - struct git_odb_backend *backend; - - int (*add)(struct git_odb_writepack *writepack, const void *data, size_t size, git_transfer_progress *stats); - int (*commit)(struct git_odb_writepack *writepack, git_transfer_progress *stats); - void (*free)(struct git_odb_writepack *writepack); -}; - -GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len); - -/** - * Constructors for in-box ODB backends. - */ -GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **out, const char *objects_dir); -GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **out, const char *objects_dir, int compression_level, int do_fsync); -GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **out, const char *index_file); - -GIT_END_DECL - -#endif diff --git a/git2/include/git2/oid.h b/git2/include/git2/oid.h deleted file mode 100644 index 6be02da6e..000000000 --- a/git2/include/git2/oid.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_oid_h__ -#define INCLUDE_git_oid_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/oid.h - * @brief Git object id routines - * @defgroup git_oid Git object id routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** Size (in bytes) of a raw/binary oid */ -#define GIT_OID_RAWSZ 20 - -/** Size (in bytes) of a hex formatted oid */ -#define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2) - -/** Minimum length (in number of hex characters, - * i.e. packets of 4 bits) of an oid prefix */ -#define GIT_OID_MINPREFIXLEN 4 - -/** Unique identity of any object (commit, tree, blob, tag). */ -typedef struct git_oid { - /** raw binary formatted id */ - unsigned char id[GIT_OID_RAWSZ]; -} git_oid; - -/** - * Parse a hex formatted object id into a git_oid. - * - * @param out oid structure the result is written into. - * @param str input hex string; must be pointing at the start of - * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (40 bytes). - * @return 0 or an error code - */ -GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str); - -/** - * Parse N characters of a hex formatted object id into a git_oid - * - * If N is odd, N-1 characters will be parsed instead. - * The remaining space in the git_oid will be set to zero. - * - * @param out oid structure the result is written into. - * @param str input hex string of at least size `length` - * @param length length of the input string - * @return 0 or an error code - */ -GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length); - -/** - * Copy an already raw oid into a git_oid structure. - * - * @param out oid structure the result is written into. - * @param raw the raw input bytes to be copied. - */ -GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw); - -/** - * Format a git_oid into a hex string. - * - * @param out output hex string; must be pointing at the start of - * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (40 bytes). Only the - * oid digits are written; a '\\0' terminator must be added - * by the caller if it is required. - * @param oid oid structure to format. - */ -GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id); - -/** - * Format a git_oid into a loose-object path string. - * - * The resulting string is "aa/...", where "aa" is the first two - * hex digits of the oid and "..." is the remaining 38 digits. - * - * @param out output hex string; must be pointing at the start of - * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (41 bytes). Only the - * oid digits are written; a '\\0' terminator must be added - * by the caller if it is required. - * @param id oid structure to format. - */ -GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id); - -/** - * Format a git_oid into a newly allocated c-string. - * - * @param oid the oid structure to format - * @return the c-string; NULL if memory is exhausted. Caller must - * deallocate the string with git__free(). - */ -GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id); - -/** - * Format a git_oid into a buffer as a hex format c-string. - * - * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting - * oid c-string will be truncated to n-1 characters. If there are - * any input parameter errors (out == NULL, n == 0, oid == NULL), - * then a pointer to an empty string is returned, so that the return - * value can always be printed. - * - * @param out the buffer into which the oid string is output. - * @param n the size of the out buffer. - * @param id the oid structure to format. - * @return the out buffer pointer, assuming no input parameter - * errors, otherwise a pointer to an empty string. - */ -GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id); - -/** - * Copy an oid from one structure to another. - * - * @param out oid structure the result is written into. - * @param src oid structure to copy from. - */ -GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src); - -/** - * Compare two oid structures. - * - * @param a first oid structure. - * @param b second oid structure. - * @return <0, 0, >0 if a < b, a == b, a > b. - */ -GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b) -{ - const unsigned char *sha1 = a->id; - const unsigned char *sha2 = b->id; - int i; - - for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) { - if (*sha1 != *sha2) - return *sha1 - *sha2; - } - - return 0; -} - -/** - * Compare two oid structures for equality - * - * @param a first oid structure. - * @param b second oid structure. - * @return true if equal, false otherwise - */ -GIT_INLINE(int) git_oid_equal(const git_oid *a, const git_oid *b) -{ - return !git_oid_cmp(a, b); -} - -/** - * Compare the first 'len' hexadecimal characters (packets of 4 bits) - * of two oid structures. - * - * @param a first oid structure. - * @param b second oid structure. - * @param len the number of hex chars to compare - * @return 0 in case of a match - */ -GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len); - -/** - * Check if an oid equals an hex formatted object id. - * - * @param id oid structure. - * @param str input hex string of an object id. - * @return GIT_ENOTOID if str is not a valid hex string, - * 0 in case of a match, GIT_ERROR otherwise. - */ -GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str); - -/** - * Check is an oid is all zeros. - * - * @return 1 if all zeros, 0 otherwise. - */ -GIT_EXTERN(int) git_oid_iszero(const git_oid *id); - -/** - * OID Shortener object - */ -typedef struct git_oid_shorten git_oid_shorten; - -/** - * Create a new OID shortener. - * - * The OID shortener is used to process a list of OIDs - * in text form and return the shortest length that would - * uniquely identify all of them. - * - * E.g. look at the result of `git log --abbrev`. - * - * @param min_length The minimal length for all identifiers, - * which will be used even if shorter OIDs would still - * be unique. - * @return a `git_oid_shorten` instance, NULL if OOM - */ -GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length); - -/** - * Add a new OID to set of shortened OIDs and calculate - * the minimal length to uniquely identify all the OIDs in - * the set. - * - * The OID is expected to be a 40-char hexadecimal string. - * The OID is owned by the user and will not be modified - * or freed. - * - * For performance reasons, there is a hard-limit of how many - * OIDs can be added to a single set (around ~22000, assuming - * a mostly randomized distribution), which should be enough - * for any kind of program, and keeps the algorithm fast and - * memory-efficient. - * - * Attempting to add more than those OIDs will result in a - * GIT_ENOMEM error - * - * @param os a `git_oid_shorten` instance - * @param text_id an OID in text form - * @return the minimal length to uniquely identify all OIDs - * added so far to the set; or an error code (<0) if an - * error occurs. - */ -GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id); - -/** - * Free an OID shortener instance - * - * @param os a `git_oid_shorten` instance - */ -GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/pack.h b/git2/include/git2/pack.h deleted file mode 100644 index bc628c56a..000000000 --- a/git2/include/git2/pack.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_pack_h__ -#define INCLUDE_git_pack_h__ - -#include "common.h" -#include "oid.h" - -/** - * @file git2/pack.h - * @brief Git pack management routines - * @defgroup git_pack Git pack management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Initialize a new packbuilder - * - * @param out The new packbuilder object - * @param repo The repository - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_packbuilder_new(git_packbuilder **out, git_repository *repo); - -/** - * Set number of threads to spawn - * - * By default, libgit2 won't spawn any threads at all; - * when set to 0, libgit2 will autodetect the number of - * CPUs. - * - * @param pb The packbuilder - * @param n Number of threads to spawn - * @return number of actual threads to be used - */ -GIT_EXTERN(unsigned int) git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n); - -/** - * Insert a single object - * - * For an optimal pack it's mandatory to insert objects in recency order, - * commits followed by trees and blobs. - * - * @param pb The packbuilder - * @param id The oid of the commit - * @param name The name; might be NULL - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_packbuilder_insert(git_packbuilder *pb, const git_oid *id, const char *name); - -/** - * Insert a root tree object - * - * This will add the tree as well as all referenced trees and blobs. - * - * @param pb The packbuilder - * @param id The oid of the root tree - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *id); - -/** - * Write the new pack and the corresponding index to path - * - * @param pb The packbuilder - * @param path Directory to store the new pack and index - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_packbuilder_write(git_packbuilder *pb, const char *file); - -/** - * Create the new pack and pass each object to the callback - * - * @param pb the packbuilder - * @param cb the callback to call with each packed object's buffer - * @param payload the callback's data - * @return 0 or an error code - */ -typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload); -GIT_EXTERN(int) git_packbuilder_foreach(git_packbuilder *pb, git_packbuilder_foreach_cb cb, void *payload); - -/** - * Get the total number of objects the packbuilder will write out - * - * @param pb the packbuilder - * @return - */ -GIT_EXTERN(uint32_t) git_packbuilder_object_count(git_packbuilder *pb); - -/** - * Get the number of objects the packbuilder has already written out - * - * @param pb the packbuilder - * @return - */ -GIT_EXTERN(uint32_t) git_packbuilder_written(git_packbuilder *pb); - -/** - * Free the packbuilder and all associated data - * - * @param pb The packbuilder - */ -GIT_EXTERN(void) git_packbuilder_free(git_packbuilder *pb); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/push.h b/git2/include/git2/push.h deleted file mode 100644 index 51f059ac4..000000000 --- a/git2/include/git2/push.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_push_h__ -#define INCLUDE_git_push_h__ - -#include "common.h" - -/** - * @file git2/push.h - * @brief Git push management functions - * @defgroup git_push push management functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new push object - * - * @param out New push object - * @param remote Remote instance - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_push_new(git_push **out, git_remote *remote); - -/** - * Add a refspec to be pushed - * - * @param push The push object - * @param refspec Refspec string - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_push_add_refspec(git_push *push, const char *refspec); - -/** - * Actually push all given refspecs - * - * @param push The push object - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_push_finish(git_push *push); - -/** - * Check if remote side successfully unpacked - * - * @param push The push object - * - * @return true if equal, false otherwise - */ -GIT_EXTERN(int) git_push_unpack_ok(git_push *push); - -/** - * Call callback `cb' on each status - * - * @param push The push object - * @param cb The callback to call on each object - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_push_status_foreach(git_push *push, - int (*cb)(const char *ref, const char *msg, void *data), - void *data); - -/** - * Free the given push object - * - * @param push The push object - */ -GIT_EXTERN(void) git_push_free(git_push *push); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/reflog.h b/git2/include/git2/reflog.h deleted file mode 100644 index 4944530af..000000000 --- a/git2/include/git2/reflog.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_reflog_h__ -#define INCLUDE_git_reflog_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/reflog.h - * @brief Git reflog management routines - * @defgroup git_reflog Git reflog management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Read the reflog for the given reference - * - * If there is no reflog file for the given - * reference yet, an empty reflog object will - * be returned. - * - * The reflog must be freed manually by using - * git_reflog_free(). - * - * @param out pointer to reflog - * @param ref reference to read the reflog for - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_read(git_reflog **out, const git_reference *ref); - -/** - * Write an existing in-memory reflog object back to disk - * using an atomic file lock. - * - * @param reflog an existing reflog object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_write(git_reflog *reflog); - -/** - * Add a new entry to the reflog. - * - * `msg` is optional and can be NULL. - * - * @param reflog an existing reflog object - * @param id the OID the reference is now pointing to - * @param committer the signature of the committer - * @param msg the reflog message - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const git_signature *committer, const char *msg); - -/** - * Rename the reflog for the given reference - * - * The reflog to be renamed is expected to already exist - * - * The new name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param ref the reference - * @param name the new name of the reference - * @return 0 on success, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *name); - -/** - * Delete the reflog for the given reference - * - * @param ref the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_delete(git_reference *ref); - -/** - * Get the number of log entries in a reflog - * - * @param reflog the previously loaded reflog - * @return the number of log entries - */ -GIT_EXTERN(size_t) git_reflog_entrycount(git_reflog *reflog); - -/** - * Lookup an entry by its index - * - * Requesting the reflog entry with an index of 0 (zero) will - * return the most recently created entry. - * - * @param reflog a previously loaded reflog - * @param idx the position of the entry to lookup. Should be greater than or - * equal to 0 (zero) and less than `git_reflog_entrycount()`. - * @return the entry; NULL if not found - */ -GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog, size_t idx); - -/** - * Remove an entry from the reflog by its index - * - * To ensure there's no gap in the log history, set `rewrite_previous_entry` - * param value to 1. When deleting entry `n`, member old_oid of entry `n-1` - * (if any) will be updated with the value of member new_oid of entry `n+1`. - * - * @param reflog a previously loaded reflog. - * - * @param idx the position of the entry to remove. Should be greater than or - * equal to 0 (zero) and less than `git_reflog_entrycount()`. - * - * @param rewrite_previous_entry 1 to rewrite the history; 0 otherwise. - * - * @return 0 on success, GIT_ENOTFOUND if the entry doesn't exist - * or an error code. - */ -GIT_EXTERN(int) git_reflog_drop( - git_reflog *reflog, - size_t idx, - int rewrite_previous_entry); - -/** - * Get the old oid - * - * @param entry a reflog entry - * @return the old oid - */ -GIT_EXTERN(const git_oid *) git_reflog_entry_id_old(const git_reflog_entry *entry); - -/** - * Get the new oid - * - * @param entry a reflog entry - * @return the new oid at this time - */ -GIT_EXTERN(const git_oid *) git_reflog_entry_id_new(const git_reflog_entry *entry); - -/** - * Get the committer of this entry - * - * @param entry a reflog entry - * @return the committer - */ -GIT_EXTERN(const git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry); - -/** - * Get the log message - * - * @param entry a reflog entry - * @return the log msg - */ -GIT_EXTERN(const char *) git_reflog_entry_message(const git_reflog_entry *entry); - -/** - * Free the reflog - * - * @param reflog reflog to free - */ -GIT_EXTERN(void) git_reflog_free(git_reflog *reflog); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/refs.h b/git2/include/git2/refs.h deleted file mode 100644 index a0abbc339..000000000 --- a/git2/include/git2/refs.h +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_refs_h__ -#define INCLUDE_git_refs_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "strarray.h" - -/** - * @file git2/refs.h - * @brief Git reference management routines - * @defgroup git_reference Git reference management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a reference by name in a repository. - * - * The returned reference must be freed by the user. - * - * The name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param out pointer to the looked-up reference - * @param repo the repository to look up the reference - * @param name the long name for the reference (e.g. HEAD, refs/heads/master, refs/tags/v0.1.0, ...) - * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code. - */ -GIT_EXTERN(int) git_reference_lookup(git_reference **out, git_repository *repo, const char *name); - -/** - * Lookup a reference by name and resolve immediately to OID. - * - * This function provides a quick way to resolve a reference name straight - * through to the object id that it refers to. This avoids having to - * allocate or free any `git_reference` objects for simple situations. - * - * The name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param out Pointer to oid to be filled in - * @param repo The repository in which to look up the reference - * @param name The long name for the reference - * @return 0 on success, ENOTFOUND, EINVALIDSPEC or an error code. - */ -GIT_EXTERN(int) git_reference_name_to_id( - git_oid *out, git_repository *repo, const char *name); - -/** - * Create a new symbolic reference. - * - * A symbolic reference is a reference name that refers to another - * reference name. If the other name moves, the symbolic name will move, - * too. As a simple example, the "HEAD" reference might refer to - * "refs/heads/master" while on the "master" branch of a repository. - * - * The symbolic reference will be created in the repository and written to - * the disk. The generated reference object must be freed by the user. - * - * Valid reference names must follow one of two patterns: - * - * 1. Top-level names must contain only capital letters and underscores, - * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - * 2. Names prefixed with "refs/" can be almost anything. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * This function will return an error if a reference already exists with the - * given name unless `force` is true, in which case it will be overwritten. - * - * @param out Pointer to the newly created reference - * @param repo Repository where that reference will live - * @param name The name of the reference - * @param target The target of the reference - * @param force Overwrite existing references - * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reference_symbolic_create(git_reference **out, git_repository *repo, const char *name, const char *target, int force); - -/** - * Create a new direct reference. - * - * A direct reference (also called an object id reference) refers directly - * to a specific object id (a.k.a. OID or SHA) in the repository. The id - * permanently refers to the object (although the reference itself can be - * moved). For example, in libgit2 the direct ref "refs/tags/v0.17.0" - * refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977. - * - * The direct reference will be created in the repository and written to - * the disk. The generated reference object must be freed by the user. - * - * Valid reference names must follow one of two patterns: - * - * 1. Top-level names must contain only capital letters and underscores, - * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - * 2. Names prefixed with "refs/" can be almost anything. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * This function will return an error if a reference already exists with the - * given name unless `force` is true, in which case it will be overwritten. - * - * @param out Pointer to the newly created reference - * @param repo Repository where that reference will live - * @param name The name of the reference - * @param id The object id pointed to by the reference. - * @param force Overwrite existing references - * @return 0 on success, EEXISTS, EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, const char *name, const git_oid *id, int force); - -/** - * Get the OID pointed to by a direct reference. - * - * Only available if the reference is direct (i.e. an object id reference, - * not a symbolic one). - * - * To find the OID of a symbolic ref, call `git_reference_resolve()` and - * then this function (or maybe use `git_reference_name_to_oid()` to - * directly resolve a reference name all the way through to an OID). - * - * @param ref The reference - * @return a pointer to the oid if available, NULL otherwise - */ -GIT_EXTERN(const git_oid *) git_reference_target(const git_reference *ref); - -/** - * Get full name to the reference pointed to by a symbolic reference. - * - * Only available if the reference is symbolic. - * - * @param ref The reference - * @return a pointer to the name if available, NULL otherwise - */ -GIT_EXTERN(const char *) git_reference_symbolic_target(const git_reference *ref); - -/** - * Get the type of a reference. - * - * Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC) - * - * @param ref The reference - * @return the type - */ -GIT_EXTERN(git_ref_t) git_reference_type(const git_reference *ref); - -/** - * Get the full name of a reference. - * - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param ref The reference - * @return the full name for the ref - */ -GIT_EXTERN(const char *) git_reference_name(const git_reference *ref); - -/** - * Resolve a symbolic reference to a direct reference. - * - * This method iteratively peels a symbolic reference until it resolves to - * a direct reference to an OID. - * - * The peeled reference is returned in the `resolved_ref` argument, and - * must be freed manually once it's no longer needed. - * - * If a direct reference is passed as an argument, a copy of that - * reference is returned. This copy must be manually freed too. - * - * @param resolved_ref Pointer to the peeled reference - * @param ref The reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_resolve(git_reference **out, const git_reference *ref); - -/** - * Get the repository where a reference resides. - * - * @param ref The reference - * @return a pointer to the repo - */ -GIT_EXTERN(git_repository *) git_reference_owner(const git_reference *ref); - -/** - * Set the symbolic target of a reference. - * - * The reference must be a symbolic reference, otherwise this will fail. - * - * The reference will be automatically updated in memory and on disk. - * - * The target name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param ref The reference - * @param target The new target for the reference - * @return 0 on success, EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_reference_symbolic_set_target(git_reference *ref, const char *target); - -/** - * Set the OID target of a reference. - * - * The reference must be a direct reference, otherwise this will fail. - * - * The reference will be automatically updated in memory and on disk. - * - * @param ref The reference - * @param id The new target OID for the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const git_oid *id); - -/** - * Rename an existing reference. - * - * This method works for both direct and symbolic references. - * - * The new name will be checked for validity. - * See `git_reference_create_symbolic()` for rules about valid names. - * - * The given git_reference will be updated in place. - * - * The reference will be immediately renamed in-memory and on disk. - * - * If the `force` flag is not enabled, and there's already - * a reference with the given name, the renaming will fail. - * - * IMPORTANT: - * The user needs to write a proper reflog entry if the - * reflog is enabled for the repository. We only rename - * the reflog if it exists. - * - * @param ref The reference to rename - * @param name The new name for the reference - * @param force Overwrite an existing reference - * @return 0 on success, EINVALIDSPEC, EEXISTS or an error code - * - */ -GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *name, int force); - -/** - * Delete an existing reference. - * - * This method works for both direct and symbolic references. - * - * The reference will be immediately removed on disk and from memory - * (i.e. freed). The given reference pointer will no longer be valid. - * - * @param ref The reference to remove - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_delete(git_reference *ref); - -/** - * Pack all the loose references in the repository. - * - * This method will load into the cache all the loose - * references on the repository and update the - * `packed-refs` file with them. - * - * Once the `packed-refs` file has been written properly, - * the loose references will be removed from disk. - * - * @param repo Repository where the loose refs will be packed - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_packall(git_repository *repo); - -/** - * Fill a list with all the references that can be found in a repository. - * - * Using the `list_flags` parameter, the listed references may be filtered - * by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of - * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`. - * For convenience, use the value `GIT_REF_LISTALL` to obtain all - * references, including packed ones. - * - * The string array will be filled with the names of all references; these - * values are owned by the user and should be free'd manually when no - * longer needed, using `git_strarray_free()`. - * - * @param array Pointer to a git_strarray structure where - * the reference names will be stored - * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference listing - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags); - -typedef int (*git_reference_foreach_cb)(const char *refname, void *payload); - -/** - * Perform a callback on each reference in the repository. - * - * Using the `list_flags` parameter, the references may be filtered by - * type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of - * `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`. - * For convenience, use the value `GIT_REF_LISTALL` to obtain all - * references, including packed ones. - * - * The `callback` function will be called for each reference in the - * repository, receiving the name of the reference and the `payload` value - * passed to this method. Returning a non-zero value from the callback - * will terminate the iteration. - * - * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference listing. - * @param callback Function which will be called for every listed ref - * @param payload Additional data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_reference_foreach( - git_repository *repo, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); - -/** - * Check if a reference has been loaded from a packfile. - * - * @param ref A git reference - * @return 0 in case it's not packed; 1 otherwise - */ -GIT_EXTERN(int) git_reference_is_packed(git_reference *ref); - -/** - * Reload a reference from disk. - * - * Reference pointers can become outdated if the Git repository is - * accessed simultaneously by other clients while the library is open. - * - * This method forces a reload of the reference from disk, to ensure that - * the provided information is still reliable. - * - * If the reload fails (e.g. the reference no longer exists on disk, or - * has become corrupted), an error code will be returned and the reference - * pointer will be invalidated and freed. - * - * @param ref The reference to reload - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_reference_reload(git_reference *ref); - -/** - * Free the given reference. - * - * @param ref git_reference - */ -GIT_EXTERN(void) git_reference_free(git_reference *ref); - -/** - * Compare two references. - * - * @param ref1 The first git_reference - * @param ref2 The second git_reference - * @return 0 if the same, else a stable but meaningless ordering. - */ -GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); - -/** - * Perform a callback on each reference in the repository whose name - * matches the given pattern. - * - * This function acts like `git_reference_foreach()` with an additional - * pattern match being applied to the reference name before issuing the - * callback function. See that function for more information. - * - * The pattern is matched using fnmatch or "glob" style where a '*' matches - * any sequence of letters, a '?' matches any letter, and square brackets - * can be used to define character ranges (such as "[0-9]" for digits). - * - * @param repo Repository where to find the refs - * @param glob Pattern to match (fnmatch-style) against reference name. - * @param list_flags Filtering flags for the reference listing. - * @param callback Function which will be called for every listed ref - * @param payload Additional data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_reference_foreach_glob( - git_repository *repo, - const char *glob, - unsigned int list_flags, - git_reference_foreach_cb callback, - void *payload); - -/** - * Check if a reflog exists for the specified reference. - * - * @param ref A git reference - * - * @return 0 when no reflog can be found, 1 when it exists; - * otherwise an error code. - */ -GIT_EXTERN(int) git_reference_has_log(git_reference *ref); - -/** - * Check if a reference is a local branch. - * - * @param ref A git reference - * - * @return 1 when the reference lives in the refs/heads - * namespace; 0 otherwise. - */ -GIT_EXTERN(int) git_reference_is_branch(git_reference *ref); - -/** - * Check if a reference is a remote tracking branch - * - * @param ref A git reference - * - * @return 1 when the reference lives in the refs/remotes - * namespace; 0 otherwise. - */ -GIT_EXTERN(int) git_reference_is_remote(git_reference *ref); - - -typedef enum { - GIT_REF_FORMAT_NORMAL = 0, - - /** - * Control whether one-level refnames are accepted - * (i.e., refnames that do not contain multiple /-separated - * components). Those are expected to be written only using - * uppercase letters and underscore (FETCH_HEAD, ...) - */ - GIT_REF_FORMAT_ALLOW_ONELEVEL = (1 << 0), - - /** - * Interpret the provided name as a reference pattern for a - * refspec (as used with remote repositories). If this option - * is enabled, the name is allowed to contain a single * () - * in place of a one full pathname component - * (e.g., foo//bar but not foo/bar). - */ - GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1), -} git_reference_normalize_t; - -/** - * Normalize reference name and check validity. - * - * This will normalize the reference name by removing any leading slash - * '/' characters and collapsing runs of adjacent slashes between name - * components into a single slash. - * - * Once normalized, if the reference name is valid, it will be returned in - * the user allocated buffer. - * - * See `git_reference_create_symbolic()` for rules about valid names. - * - * @param buffer_out User allocated buffer to store normalized name - * @param buffer_size Size of buffer_out - * @param name Reference name to be checked. - * @param flags Flags to constrain name validation rules - see the - * GIT_REF_FORMAT constants above. - * @return 0 on success, GIT_EBUFS if buffer is too small, EINVALIDSPEC - * or an error code. - */ -GIT_EXTERN(int) git_reference_normalize_name( - char *buffer_out, - size_t buffer_size, - const char *name, - unsigned int flags); - -/** - * Recursively peel reference until object of the specified type is found. - * - * The retrieved `peeled` object is owned by the repository - * and should be closed with the `git_object_free` method. - * - * If you pass `GIT_OBJ_ANY` as the target type, then the object - * will be peeled until a non-tag object is met. - * - * @param peeled Pointer to the peeled git_object - * @param ref The reference to be processed - * @param target_type The type of the requested object (GIT_OBJ_COMMIT, - * GIT_OBJ_TAG, GIT_OBJ_TREE, GIT_OBJ_BLOB or GIT_OBJ_ANY). - * @return 0 on success, GIT_EAMBIGUOUS, GIT_ENOTFOUND or an error code - */ -GIT_EXTERN(int) git_reference_peel( - git_object **out, - git_reference *ref, - git_otype type); - -/** - * Ensure the reference name is well-formed. - * - * Valid reference names must follow one of two patterns: - * - * 1. Top-level names must contain only capital letters and underscores, - * and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - * 2. Names prefixed with "refs/" can be almost anything. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * @param refname name to be checked. - * @return 1 if the reference name is acceptable; 0 if it isn't - */ -GIT_EXTERN(int) git_reference_is_valid_name(const char *refname); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/refspec.h b/git2/include/git2/refspec.h deleted file mode 100644 index ee06f8eca..000000000 --- a/git2/include/git2/refspec.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_refspec_h__ -#define INCLUDE_git_refspec_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/refspec.h - * @brief Git refspec attributes - * @defgroup git_refspec Git refspec attributes - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Get the source specifier - * - * @param refspec the refspec - * @return the refspec's source specifier - */ -GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec); - -/** - * Get the destination specifier - * - * @param refspec the refspec - * @return the refspec's destination specifier - */ -GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec); - -/** - * Get the force update setting - * - * @param refspec the refspec - * @return 1 if force update has been set, 0 otherwise - */ -GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec); - -/** - * Check if a refspec's source descriptor matches a reference - * - * @param refspec the refspec - * @param refname the name of the reference to check - * @return 1 if the refspec matches, 0 otherwise - */ -GIT_EXTERN(int) git_refspec_src_matches(const git_refspec *refspec, const char *refname); - -/** - * Transform a reference to its target following the refspec's rules - * - * @param out where to store the target name - * @param outlen the size of the `out` buffer - * @param spec the refspec - * @param name the name of the reference to transform - * @return 0, GIT_EBUFS or another error - */ -GIT_EXTERN(int) git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name); - -GIT_END_DECL - -#endif diff --git a/git2/include/git2/remote.h b/git2/include/git2/remote.h deleted file mode 100644 index a0f5d5246..000000000 --- a/git2/include/git2/remote.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_remote_h__ -#define INCLUDE_git_remote_h__ - -#include "common.h" -#include "repository.h" -#include "refspec.h" -#include "net.h" -#include "indexer.h" -#include "strarray.h" -#include "transport.h" - -/** - * @file git2/remote.h - * @brief Git remote management functions - * @defgroup git_remote remote management functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -typedef int (*git_remote_rename_problem_cb)(const char *problematic_refspec, void *payload); -/* - * TODO: This functions still need to be implemented: - * - _listcb/_foreach - * - _add - * - _rename - * - _del (needs support from config) - */ - -/** - * Add a remote with the default fetch refspec to the repository's configuration. This - * calls git_remote_save before returning. - * - * @param out the resulting remote - * @param repo the repository in which to create the remote - * @param name the remote's name - * @param url the remote's url - * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code - */ -GIT_EXTERN(int) git_remote_create( - git_remote **out, - git_repository *repo, - const char *name, - const char *url); - -/** - * Create a remote in memory - * - * Create a remote with the given refspec in memory. You can use - * this when you have a URL instead of a remote's name. Note that in-memory - * remotes cannot be converted to persisted remotes. - * - * The name, when provided, will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param out pointer to the new remote object - * @param repo the associated repository. May be NULL for a "dangling" remote. - * @param fetch the fetch refspec to use for this remote. May be NULL for defaults. - * @param url the remote repository's URL - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_create_inmemory( - git_remote **out, - git_repository *repo, - const char *fetch, - const char *url); - -/** - * Sets the owning repository for the remote. This is only allowed on - * dangling remotes. - * - * @param remote the remote to configure - * @param repo the repository that will own the remote - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_set_repository(git_remote *remote, git_repository *repo); - -/** - * Get the information for a particular remote - * - * The name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param out pointer to the new remote object - * @param repo the associated repository - * @param name the remote's name - * @return 0, GIT_ENOTFOUND, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const char *name); - -/** - * Save a remote to its repository's configuration - * - * One can't save a in-memory remote. Doing so will - * result in a GIT_EINVALIDSPEC being returned. - * - * @param remote the remote to save to config - * @return 0, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_remote_save(const git_remote *remote); - -/** - * Get the remote's name - * - * @param remote the remote - * @return a pointer to the name or NULL for in-memory remotes - */ -GIT_EXTERN(const char *) git_remote_name(const git_remote *remote); - -/** - * Get the remote's url - * - * @param remote the remote - * @return a pointer to the url - */ -GIT_EXTERN(const char *) git_remote_url(const git_remote *remote); - -/** - * Get the remote's url for pushing - * - * @param remote the remote - * @return a pointer to the url or NULL if no special url for pushing is set - */ -GIT_EXTERN(const char *) git_remote_pushurl(const git_remote *remote); - -/** - * Set the remote's url - * - * Existing connections will not be updated. - * - * @param remote the remote - * @param url the url to set - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_url(git_remote *remote, const char* url); - -/** - * Set the remote's url for pushing - * - * Existing connections will not be updated. - * - * @param remote the remote - * @param url the url to set or NULL to clear the pushurl - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url); - -/** - * Set the remote's fetch refspec - * - * @param remote the remote - * @apram spec the new fetch refspec - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec); - -/** - * Get the fetch refspec - * - * @param remote the remote - * @return a pointer to the fetch refspec or NULL if it doesn't exist - */ -GIT_EXTERN(const git_refspec *) git_remote_fetchspec(const git_remote *remote); - -/** - * Set the remote's push refspec - * - * @param remote the remote - * @param spec the new push refspec - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec); - -/** - * Get the push refspec - * - * @param remote the remote - * @return a pointer to the push refspec or NULL if it doesn't exist - */ - -GIT_EXTERN(const git_refspec *) git_remote_pushspec(const git_remote *remote); - -/** - * Open a connection to a remote - * - * The transport is selected based on the URL. The direction argument - * is due to a limitation of the git protocol (over TCP or SSH) which - * starts up a specific binary which can only do the one or the other. - * - * @param remote the remote to connect to - * @param direction whether you want to receive or send data - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction); - -/** - * Get a list of refs at the remote - * - * The remote (or more exactly its transport) must be connected. The - * memory belongs to the remote. - * - * If you a return a non-zero value from the callback, this will stop - * looping over the refs. - * - * @param remote the remote - * @param list_cb function to call with each ref discovered at the remote - * @param payload additional data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload); - -/** - * Download the packfile - * - * Negotiate what objects should be downloaded and download the - * packfile with those objects. The packfile is downloaded with a - * temporary filename, as it's final name is not known yet. If there - * was no packfile needed (all the objects were available locally), - * filename will be NULL and the function will return success. - * - * @param remote the remote to download from - * @param progress_cb function to call with progress information. Be aware that - * this is called inline with network and indexing operations, so performance - * may be affected. - * @param progress_payload payload for the progress callback - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_download( - git_remote *remote, - git_transfer_progress_callback progress_cb, - void *payload); - -/** - * Check whether the remote is connected - * - * Check whether the remote's underlying transport is connected to the - * remote host. - * - * @param remote the remote - * @return 1 if it's connected, 0 otherwise. - */ -GIT_EXTERN(int) git_remote_connected(git_remote *remote); - -/** - * Cancel the operation - * - * At certain points in its operation, the network code checks whether - * the operation has been cancelled and if so stops the operation. - * - * @param remote the remote - */ -GIT_EXTERN(void) git_remote_stop(git_remote *remote); - -/** - * Disconnect from the remote - * - * Close the connection to the remote and free the underlying - * transport. - * - * @param remote the remote to disconnect from - */ -GIT_EXTERN(void) git_remote_disconnect(git_remote *remote); - -/** - * Free the memory associated with a remote - * - * This also disconnects from the remote, if the connection - * has not been closed yet (using git_remote_disconnect). - * - * @param remote the remote to free - */ -GIT_EXTERN(void) git_remote_free(git_remote *remote); - -/** - * Update the tips to the new state - * - * @param remote the remote to update - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_update_tips(git_remote *remote); - -/** - * Return whether a string is a valid remote URL - * - * @param url the url to check - * @param 1 if the url is valid, 0 otherwise - */ -GIT_EXTERN(int) git_remote_valid_url(const char *url); - -/** - * Return whether the passed URL is supported by this version of the library. - * - * @param url the url to check - * @return 1 if the url is supported, 0 otherwise -*/ -GIT_EXTERN(int) git_remote_supported_url(const char* url); - -/** - * Get a list of the configured remotes for a repo - * - * The string array must be freed by the user. - * - * @param out a string array which receives the names of the remotes - * @param repo the repository to query - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo); - -/** - * Choose whether to check the server's certificate (applies to HTTPS only) - * - * @param remote the remote to configure - * @param check whether to check the server's certificate (defaults to yes) - */ -GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check); - -/** - * Set a credentials acquisition callback for this remote. If the remote is - * not available for anonymous access, then you must set this callback in order - * to provide credentials to the transport at the time of authentication - * failure so that retry can be performed. - * - * @param remote the remote to configure - * @param cred_acquire_cb The credentials acquisition callback to use (defaults - * to NULL) - */ -GIT_EXTERN(void) git_remote_set_cred_acquire_cb( - git_remote *remote, - git_cred_acquire_cb cred_acquire_cb, - void *payload); - -/** - * Sets a custom transport for the remote. The caller can use this function - * to bypass the automatic discovery of a transport by URL scheme (i.e. - * http://, https://, git://) and supply their own transport to be used - * instead. After providing the transport to a remote using this function, - * the transport object belongs exclusively to that remote, and the remote will - * free it when it is freed with git_remote_free. - * - * @param remote the remote to configure - * @param transport the transport object for the remote to use - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_set_transport( - git_remote *remote, - git_transport *transport); - -/** - * Argument to the completion callback which tells it which operation - * finished. - */ -typedef enum git_remote_completion_type { - GIT_REMOTE_COMPLETION_DOWNLOAD, - GIT_REMOTE_COMPLETION_INDEXING, - GIT_REMOTE_COMPLETION_ERROR, -} git_remote_completion_type; - -/** - * The callback settings structure - * - * Set the calbacks to be called by the remote. - */ -struct git_remote_callbacks { - unsigned int version; - void (*progress)(const char *str, int len, void *data); - int (*completion)(git_remote_completion_type type, void *data); - int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data); - void *payload; -}; - -#define GIT_REMOTE_CALLBACKS_VERSION 1 -#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION} - -/** - * Set the callbacks for a remote - * - * Note that the remote keeps its own copy of the data and you need to - * call this function again if you want to change the callbacks. - * - * @param remote the remote to configure - * @param callbacks a pointer to the user's callback settings - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); - -/** - * Get the statistics structure that is filled in by the fetch operation. - */ -GIT_EXTERN(const git_transfer_progress *) git_remote_stats(git_remote *remote); - -typedef enum { - GIT_REMOTE_DOWNLOAD_TAGS_UNSET, - GIT_REMOTE_DOWNLOAD_TAGS_NONE, - GIT_REMOTE_DOWNLOAD_TAGS_AUTO, - GIT_REMOTE_DOWNLOAD_TAGS_ALL -} git_remote_autotag_option_t; - -/** - * Retrieve the tag auto-follow setting - * - * @param remote the remote to query - * @return the auto-follow setting - */ -GIT_EXTERN(git_remote_autotag_option_t) git_remote_autotag(git_remote *remote); - -/** - * Set the tag auto-follow setting - * - * @param remote the remote to configure - * @param value a GIT_REMOTE_DOWNLOAD_TAGS value - */ -GIT_EXTERN(void) git_remote_set_autotag( - git_remote *remote, - git_remote_autotag_option_t value); - -/** - * Give the remote a new name - * - * All remote-tracking branches and configuration settings - * for the remote are updated. - * - * The new name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * A temporary in-memory remote cannot be given a name with this method. - * - * @param remote the remote to rename - * @param new_name the new name the remote should bear - * @param callback Optional callback to notify the consumer of fetch refspecs - * that haven't been automatically updated and need potential manual tweaking. - * @param payload Additional data to pass to the callback - * @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code - */ -GIT_EXTERN(int) git_remote_rename( - git_remote *remote, - const char *new_name, - git_remote_rename_problem_cb callback, - void *payload); - -/** - * Retrieve the update FETCH_HEAD setting. - * - * @param remote the remote to query - * @return the update FETCH_HEAD setting - */ -GIT_EXTERN(int) git_remote_update_fetchhead(git_remote *remote); - -/** - * Sets the update FETCH_HEAD setting. By default, FETCH_HEAD will be - * updated on every fetch. Set to 0 to disable. - * - * @param remote the remote to configure - * @param value 0 to disable updating FETCH_HEAD - */ -GIT_EXTERN(void) git_remote_set_update_fetchhead(git_remote *remote, int value); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/repository.h b/git2/include/git2/repository.h deleted file mode 100644 index e207e5bb5..000000000 --- a/git2/include/git2/repository.h +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_repository_h__ -#define INCLUDE_git_repository_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/repository.h - * @brief Git repository management routines - * @defgroup git_repository Git repository management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Open a git repository. - * - * The 'path' argument must point to either a git repository - * folder, or an existing work dir. - * - * The method will automatically detect if 'path' is a normal - * or bare repository or fail is 'path' is neither. - * - * @param out pointer to the repo which will be opened - * @param path the path to the repository - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_open(git_repository **out, const char *path); - -/** - * Create a "fake" repository to wrap an object database - * - * Create a repository object to wrap an object database to be used - * with the API when all you have is an object database. This doesn't - * have any paths associated with it, so use with care. - * - * @param out pointer to the repo - * @param odb the object database to wrap - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_wrap_odb(git_repository **out, git_odb *odb); - -/** - * Look for a git repository and copy its path in the given buffer. - * The lookup start from base_path and walk across parent directories - * if nothing has been found. The lookup ends when the first repository - * is found, or when reaching a directory referenced in ceiling_dirs - * or when the filesystem changes (in case across_fs is true). - * - * The method will automatically detect if the repository is bare - * (if there is a repository). - * - * @param path_out The user allocated buffer which will - * contain the found path. - * - * @param path_size repository_path size - * - * @param start_path The base path where the lookup starts. - * - * @param across_fs If true, then the lookup will not stop when a - * filesystem device change is detected while exploring parent directories. - * - * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR separated list of - * absolute symbolic link free paths. The lookup will stop when any - * of this paths is reached. Note that the lookup always performs on - * start_path no matter start_path appears in ceiling_dirs ceiling_dirs - * might be NULL (which is equivalent to an empty string) - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_discover( - char *path_out, - size_t path_size, - const char *start_path, - int across_fs, - const char *ceiling_dirs); - -/** - * Option flags for `git_repository_open_ext`. - * - * * GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be - * immediately found in the start_path. Do not walk up from the - * start_path looking at parent directories. - * * GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not - * continue searching across filesystem boundaries (i.e. when `st_dev` - * changes from the `stat` system call). (E.g. Searching in a user's home - * directory "/home/user/source/" will not return "/.git/" as the found - * repo if "/" is a different filesystem than "/home".) - */ -typedef enum { - GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0), - GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1), -} git_repository_open_flag_t; - -/** - * Find and open a repository with extended controls. - * - * @param out Pointer to the repo which will be opened. This can - * actually be NULL if you only want to use the error code to - * see if a repo at this path could be opened. - * @param path Path to open as git repository. If the flags - * permit "searching", then this can be a path to a subdirectory - * inside the working directory of the repository. - * @param flags A combination of the GIT_REPOSITORY_OPEN flags above. - * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR delimited list of path - * prefixes at which the search for a containing repository should - * terminate. - * @return 0 on success, GIT_ENOTFOUND if no repository could be found, - * or -1 if there was a repository but open failed for some reason - * (such as repo corruption or system errors). - */ -GIT_EXTERN(int) git_repository_open_ext( - git_repository **out, - const char *path, - unsigned int flags, - const char *ceiling_dirs); - -/** - * Free a previously allocated repository - * - * Note that after a repository is free'd, all the objects it has spawned - * will still exist until they are manually closed by the user - * with `git_object_free`, but accessing any of the attributes of - * an object without a backing repository will result in undefined - * behavior - * - * @param repo repository handle to close. If NULL nothing occurs. - */ -GIT_EXTERN(void) git_repository_free(git_repository *repo); - -/** - * Creates a new Git repository in the given folder. - * - * TODO: - * - Reinit the repository - * - * @param out pointer to the repo which will be created or reinitialized - * @param path the path to the repository - * @param is_bare if true, a Git repository without a working directory is - * created at the pointed path. If false, provided path will be - * considered as the working directory into which the .git directory - * will be created. - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_init( - git_repository **out, - const char *path, - unsigned is_bare); - -/** - * Option flags for `git_repository_init_ext`. - * - * These flags configure extra behaviors to `git_repository_init_ext`. - * In every case, the default behavior is the zero value (i.e. flag is - * not set). Just OR the flag values together for the `flags` parameter - * when initializing a new repo. Details of individual values are: - * - * * BARE - Create a bare repository with no working directory. - * * NO_REINIT - Return an EEXISTS error if the repo_path appears to - * already be an git repository. - * * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo - * path for non-bare repos (if it is not already there), but - * passing this flag prevents that behavior. - * * MKDIR - Make the repo_path (and workdir_path) as needed. Init is - * always willing to create the ".git" directory even without this - * flag. This flag tells init to create the trailing component of - * the repo and workdir paths as needed. - * * MKPATH - Recursively make all components of the repo and workdir - * paths as necessary. - * * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to - * initialize a new repo. This flags enables external templates, - * looking the "template_path" from the options if set, or the - * `init.templatedir` global config if not, or falling back on - * "/usr/share/git-core/templates" if it exists. - */ -typedef enum { - GIT_REPOSITORY_INIT_BARE = (1u << 0), - GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1), - GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2), - GIT_REPOSITORY_INIT_MKDIR = (1u << 3), - GIT_REPOSITORY_INIT_MKPATH = (1u << 4), - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5), -} git_repository_init_flag_t; - -/** - * Mode options for `git_repository_init_ext`. - * - * Set the mode field of the `git_repository_init_options` structure - * either to the custom mode that you would like, or to one of the - * following modes: - * - * * SHARED_UMASK - Use permissions configured by umask - the default. - * * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo - * to be group writable and "g+sx" for sticky group assignment. - * * SHARED_ALL - Use "--shared=all" behavior, adding world readability. - * * Anything else - Set to custom value. - */ -typedef enum { - GIT_REPOSITORY_INIT_SHARED_UMASK = 0, - GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775, - GIT_REPOSITORY_INIT_SHARED_ALL = 0002777, -} git_repository_init_mode_t; - -/** - * Extended options structure for `git_repository_init_ext`. - * - * This contains extra options for `git_repository_init_ext` that enable - * additional initialization features. The fields are: - * - * * flags - Combination of GIT_REPOSITORY_INIT flags above. - * * mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_... - * constants above, or to a custom value that you would like. - * * workdir_path - The path to the working dir or NULL for default (i.e. - * repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH, - * IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not - * the "natural" working directory, a .git gitlink file will be - * created here linking to the repo_path. - * * description - If set, this will be used to initialize the "description" - * file in the repository, instead of using the template content. - * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set, - * this contains the path to use for the template directory. If - * this is NULL, the config or default directory options will be - * used instead. - * * initial_head - The name of the head to point HEAD at. If NULL, then - * this will be treated as "master" and the HEAD ref will be set - * to "refs/heads/master". If this begins with "refs/" it will be - * used verbatim; otherwise "refs/heads/" will be prefixed. - * * origin_url - If this is non-NULL, then after the rest of the - * repository initialization is completed, an "origin" remote - * will be added pointing to this URL. - */ -typedef struct { - unsigned int version; - uint32_t flags; - uint32_t mode; - const char *workdir_path; - const char *description; - const char *template_path; - const char *initial_head; - const char *origin_url; -} git_repository_init_options; - -#define GIT_REPOSITORY_INIT_OPTIONS_VERSION 1 -#define GIT_REPOSITORY_INIT_OPTIONS_INIT {GIT_REPOSITORY_INIT_OPTIONS_VERSION} - -/** - * Create a new Git repository in the given folder with extended controls. - * - * This will initialize a new git repository (creating the repo_path - * if requested by flags) and working directory as needed. It will - * auto-detect the case sensitivity of the file system and if the - * file system supports file mode bits correctly. - * - * @param out Pointer to the repo which will be created or reinitialized. - * @param repo_path The path to the repository. - * @param opts Pointer to git_repository_init_options struct. - * @return 0 or an error code on failure. - */ -GIT_EXTERN(int) git_repository_init_ext( - git_repository **out, - const char *repo_path, - git_repository_init_options *opts); - -/** - * Retrieve and resolve the reference pointed at by HEAD. - * - * The returned `git_reference` will be owned by caller and - * `git_reference_free()` must be called when done with it to release the - * allocated memory and prevent a leak. - * - * @param out pointer to the reference which will be retrieved - * @param repo a repository object - * - * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing - * branch, GIT_ENOTFOUND when HEAD is missing; an error code otherwise - */ -GIT_EXTERN(int) git_repository_head(git_reference **out, git_repository *repo); - -/** - * Check if a repository's HEAD is detached - * - * A repository's HEAD is detached when it points directly to a commit - * instead of a branch. - * - * @param repo Repo to test - * @return 1 if HEAD is detached, 0 if it's not; error code if there - * was an error. - */ -GIT_EXTERN(int) git_repository_head_detached(git_repository *repo); - -/** - * Check if the current branch is an orphan - * - * An orphan branch is one named from HEAD but which doesn't exist in - * the refs namespace, because it doesn't have any commit to point to. - * - * @param repo Repo to test - * @return 1 if the current branch is an orphan, 0 if it's not; error - * code if there was an error - */ -GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo); - -/** - * Check if a repository is empty - * - * An empty repository has just been initialized and contains - * no references. - * - * @param repo Repo to test - * @return 1 if the repository is empty, 0 if it isn't, error code - * if the repository is corrupted - */ -GIT_EXTERN(int) git_repository_is_empty(git_repository *repo); - -/** - * Get the path of this repository - * - * This is the path of the `.git` folder for normal repositories, - * or of the repository itself for bare repositories. - * - * @param repo A repository object - * @return the path to the repository - */ -GIT_EXTERN(const char *) git_repository_path(git_repository *repo); - -/** - * Get the path of the working directory for this repository - * - * If the repository is bare, this function will always return - * NULL. - * - * @param repo A repository object - * @return the path to the working dir, if it exists - */ -GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo); - -/** - * Set the path to the working directory for this repository - * - * The working directory doesn't need to be the same one - * that contains the `.git` folder for this repository. - * - * If this repository is bare, setting its working directory - * will turn it into a normal repository, capable of performing - * all the common workdir operations (checkout, status, index - * manipulation, etc). - * - * @param repo A repository object - * @param workdir The path to a working directory - * @param update_gitlink Create/update gitlink in workdir and set config - * "core.worktree" (if workdir is not the parent of the .git directory) - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_set_workdir( - git_repository *repo, const char *workdir, int update_gitlink); - -/** - * Check if a repository is bare - * - * @param repo Repo to test - * @return 1 if the repository is bare, 0 otherwise. - */ -GIT_EXTERN(int) git_repository_is_bare(git_repository *repo); - -/** - * Get the configuration file for this repository. - * - * If a configuration file has not been set, the default - * config set for the repository will be returned, including - * global and system configurations (if they are available). - * - * The configuration file must be freed once it's no longer - * being used by the user. - * - * @param out Pointer to store the loaded config file - * @param repo A repository object - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo); - -/** - * Set the configuration file for this repository - * - * This configuration file will be used for all configuration - * queries involving this repository. - * - * The repository will keep a reference to the config file; - * the user must still free the config after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param config A Config object - */ -GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config); - -/** - * Get the Object Database for this repository. - * - * If a custom ODB has not been set, the default - * database for the repository will be returned (the one - * located in `.git/objects`). - * - * The ODB must be freed once it's no longer being used by - * the user. - * - * @param out Pointer to store the loaded ODB - * @param repo A repository object - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo); - -/** - * Set the Object Database for this repository - * - * The ODB will be used for all object-related operations - * involving this repository. - * - * The repository will keep a reference to the ODB; the user - * must still free the ODB object after setting it to the - * repository, or it will leak. - * - * @param repo A repository object - * @param odb An ODB object - */ -GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); - -/** - * Get the Index file for this repository. - * - * If a custom index has not been set, the default - * index for the repository will be returned (the one - * located in `.git/index`). - * - * The index must be freed once it's no longer being used by - * the user. - * - * @param out Pointer to store the loaded index - * @param repo A repository object - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo); - -/** - * Set the index file for this repository - * - * This index will be used for all index-related operations - * involving this repository. - * - * The repository will keep a reference to the index file; - * the user must still free the index after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param index An index object - */ -GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index); - -/** - * Retrieve git's prepared message - * - * Operations such as git revert/cherry-pick/merge with the -n option - * stop just short of creating a commit with the changes and save - * their prepared message in .git/MERGE_MSG so the next git-commit - * execution can present it to the user for them to amend if they - * wish. - * - * Use this function to get the contents of this file. Don't forget to - * remove the file after you create the commit. - * - * @param out Buffer to write data into or NULL to just read required size - * @param len Length of buffer in bytes - * @param repo Repository to read prepared message from - * @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error - */ -GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo); - -/** - * Remove git's prepared message. - * - * Remove the message that `git_repository_message` retrieves. - */ -GIT_EXTERN(int) git_repository_message_remove(git_repository *repo); - -/** - * Remove all the metadata associated with an ongoing git merge, including - * MERGE_HEAD, MERGE_MSG, etc. - * - * @param repo A repository object - * @return 0 on success, or error - */ -GIT_EXTERN(int) git_repository_merge_cleanup(git_repository *repo); - -typedef int (*git_repository_fetchhead_foreach_cb)(const char *ref_name, - const char *remote_url, - const git_oid *oid, - unsigned int is_merge, - void *payload); - -/** - * Call callback 'callback' for each entry in the given FETCH_HEAD file. - * - * @param repo A repository object - * @param callback Callback function - * @param payload Pointer to callback data (optional) - * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error - */ -GIT_EXTERN(int) git_repository_fetchhead_foreach(git_repository *repo, - git_repository_fetchhead_foreach_cb callback, - void *payload); - -typedef int (*git_repository_mergehead_foreach_cb)(const git_oid *oid, - void *payload); - -/** - * If a merge is in progress, call callback 'cb' for each commit ID in the - * MERGE_HEAD file. - * - * @param repo A repository object - * @param callback Callback function - * @param apyload Pointer to callback data (optional) - * @return 0 on success, GIT_ENOTFOUND, GIT_EUSER or error - */ -GIT_EXTERN(int) git_repository_mergehead_foreach(git_repository *repo, - git_repository_mergehead_foreach_cb callback, - void *payload); - -/** - * Calculate hash of file using repository filtering rules. - * - * If you simply want to calculate the hash of a file on disk with no filters, - * you can just use the `git_odb_hashfile()` API. However, if you want to - * hash a file in the repository and you want to apply filtering rules (e.g. - * crlf filters) before generating the SHA, then use this function. - * - * @param out Output value of calculated SHA - * @param repo Repository pointer - * @param path Path to file on disk whose contents should be hashed. If the - * repository is not NULL, this can be a relative path. - * @param type The object type to hash as (e.g. GIT_OBJ_BLOB) - * @param as_path The path to use to look up filtering rules. If this is - * NULL, then the `path` parameter will be used instead. If - * this is passed as the empty string, then no filters will be - * applied when calculating the hash. - */ -GIT_EXTERN(int) git_repository_hashfile( - git_oid *out, - git_repository *repo, - const char *path, - git_otype type, - const char *as_path); - -/** - * Make the repository HEAD point to the specified reference. - * - * If the provided reference points to a Tree or a Blob, the HEAD is - * unaltered and -1 is returned. - * - * If the provided reference points to a branch, the HEAD will point - * to that branch, staying attached, or become attached if it isn't yet. - * If the branch doesn't exist yet, no error will be return. The HEAD - * will then be attached to an unborn branch. - * - * Otherwise, the HEAD will be detached and will directly point to - * the Commit. - * - * @param repo Repository pointer - * @param refname Canonical name of the reference the HEAD should point at - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_repository_set_head( - git_repository* repo, - const char* refname); - -/** - * Make the repository HEAD directly point to the Commit. - * - * If the provided committish cannot be found in the repository, the HEAD - * is unaltered and GIT_ENOTFOUND is returned. - * - * If the provided commitish cannot be peeled into a commit, the HEAD - * is unaltered and -1 is returned. - * - * Otherwise, the HEAD will eventually be detached and will directly point to - * the peeled Commit. - * - * @param repo Repository pointer - * @param commitish Object id of the Commit the HEAD should point to - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_repository_set_head_detached( - git_repository* repo, - const git_oid* commitish); - -/** - * Detach the HEAD. - * - * If the HEAD is already detached and points to a Commit, 0 is returned. - * - * If the HEAD is already detached and points to a Tag, the HEAD is - * updated into making it point to the peeled Commit, and 0 is returned. - * - * If the HEAD is already detached and points to a non commitish, the HEAD is - * unaltered, and -1 is returned. - * - * Otherwise, the HEAD will be detached and point to the peeled Commit. - * - * @param repo Repository pointer - * @return 0 on success, GIT_EORPHANEDHEAD when HEAD points to a non existing - * branch or an error code - */ -GIT_EXTERN(int) git_repository_detach_head( - git_repository* repo); - -typedef enum { - GIT_REPOSITORY_STATE_NONE, - GIT_REPOSITORY_STATE_MERGE, - GIT_REPOSITORY_STATE_REVERT, - GIT_REPOSITORY_STATE_CHERRY_PICK, - GIT_REPOSITORY_STATE_BISECT, - GIT_REPOSITORY_STATE_REBASE, - GIT_REPOSITORY_STATE_REBASE_INTERACTIVE, - GIT_REPOSITORY_STATE_REBASE_MERGE, - GIT_REPOSITORY_STATE_APPLY_MAILBOX, - GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE, -} git_repository_state_t; - -/** - * Determines the status of a git repository - ie, whether an operation - * (merge, cherry-pick, etc) is in progress. - * - * @param repo Repository pointer - * @return The state of the repository - */ -GIT_EXTERN(int) git_repository_state(git_repository *repo); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/reset.h b/git2/include/git2/reset.h deleted file mode 100644 index 00d25dff0..000000000 --- a/git2/include/git2/reset.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_reset_h__ -#define INCLUDE_git_reset_h__ - -/** - * @file git2/reset.h - * @brief Git reset management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Kinds of reset operation - */ -typedef enum { - GIT_RESET_SOFT = 1, /** Move the head to the given commit */ - GIT_RESET_MIXED = 2, /** SOFT plus reset index to the commit */ - GIT_RESET_HARD = 3, /** MIXED plus changes in working tree discarded */ -} git_reset_t; - -/** - * Sets the current head to the specified commit oid and optionally - * resets the index and working tree to match. - * - * SOFT reset means the head will be moved to the commit. - * - * MIXED reset will trigger a SOFT reset, plus the index will be replaced - * with the content of the commit tree. - * - * HARD reset will trigger a MIXED reset and the working directory will be - * replaced with the content of the index. (Untracked and ignored files - * will be left alone, however.) - * - * TODO: Implement remaining kinds of resets. - * - * @param repo Repository where to perform the reset operation. - * - * @param target Object to which the Head should be moved to. This object - * must belong to the given `repo` and can either be a git_commit or a - * git_tag. When a git_tag is being passed, it should be dereferencable - * to a git_commit which oid will be used as the target of the branch. - * - * @param reset_type Kind of reset operation to perform. - * - * @return 0 on success or an error code < 0 - */ -GIT_EXTERN(int) git_reset( - git_repository *repo, git_object *target, git_reset_t reset_type); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/revparse.h b/git2/include/git2/revparse.h deleted file mode 100644 index 6edb7767c..000000000 --- a/git2/include/git2/revparse.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_revparse_h__ -#define INCLUDE_git_revparse_h__ - -#include "common.h" -#include "types.h" - - -/** - * @file git2/revparse.h - * @brief Git revision parsing routines - * @defgroup git_revparse Git revision parsing routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Find an object, as specified by a revision string. See `man gitrevisions`, or the documentation - * for `git rev-parse` for information on the syntax accepted. - * - * @param out pointer to output object - * @param repo the repository to search in - * @param spec the textual specification for an object - * @return 0 on success, GIT_ENOTFOUND, GIT_EAMBIGUOUS, - * GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_revparse_single(git_object **out, git_repository *repo, const char *spec); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/revwalk.h b/git2/include/git2/revwalk.h deleted file mode 100644 index ad57b622e..000000000 --- a/git2/include/git2/revwalk.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_revwalk_h__ -#define INCLUDE_git_revwalk_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/revwalk.h - * @brief Git revision traversal routines - * @defgroup git_revwalk Git revision traversal routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Sort the repository contents in no particular ordering; - * this sorting is arbitrary, implementation-specific - * and subject to change at any time. - * This is the default sorting for new walkers. - */ -#define GIT_SORT_NONE (0) - -/** - * Sort the repository contents in topological order - * (parents before children); this sorting mode - * can be combined with time sorting. - */ -#define GIT_SORT_TOPOLOGICAL (1 << 0) - -/** - * Sort the repository contents by commit time; - * this sorting mode can be combined with - * topological sorting. - */ -#define GIT_SORT_TIME (1 << 1) - -/** - * Iterate through the repository contents in reverse - * order; this sorting mode can be combined with - * any of the above. - */ -#define GIT_SORT_REVERSE (1 << 2) - -/** - * Allocate a new revision walker to iterate through a repo. - * - * This revision walker uses a custom memory pool and an internal - * commit cache, so it is relatively expensive to allocate. - * - * For maximum performance, this revision walker should be - * reused for different walks. - * - * This revision walker is *not* thread safe: it may only be - * used to walk a repository on a single thread; however, - * it is possible to have several revision walkers in - * several different threads walking the same repository. - * - * @param out pointer to the new revision walker - * @param repo the repo to walk through - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_new(git_revwalk **out, git_repository *repo); - -/** - * Reset the revision walker for reuse. - * - * This will clear all the pushed and hidden commits, and - * leave the walker in a blank state (just like at - * creation) ready to receive new commit pushes and - * start a new walk. - * - * The revision walk is automatically reset when a walk - * is over. - * - * @param walker handle to reset. - */ -GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker); - -/** - * Mark a commit to start traversal from. - * - * The given OID must belong to a commit on the walked - * repository. - * - * The given commit will be used as one of the roots - * when starting the revision walk. At least one commit - * must be pushed the repository before a walk can - * be started. - * - * @param walk the walker being used for the traversal. - * @param id the oid of the commit to start from. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *id); - -/** - * Push matching references - * - * The OIDs pointed to by the references that match the given glob - * pattern will be pushed to the revision walker. - * - * A leading 'refs/' is implied if not present as well as a trailing - * '/ *' if the glob lacks '?', '*' or '['. - * - * @param walk the walker being used for the traversal - * @param glob the glob pattern references should match - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob); - -/** - * Push the repository's HEAD - * - * @param walk the walker being used for the traversal - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk); - -/** - * Mark a commit (and its ancestors) uninteresting for the output. - * - * The given OID must belong to a commit on the walked - * repository. - * - * The resolved commit and all its parents will be hidden from the - * output on the revision walk. - * - * @param walk the walker being used for the traversal. - * @param commit_id the oid of commit that will be ignored during the traversal - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *commit_id); - -/** - * Hide matching references. - * - * The OIDs pointed to by the references that match the given glob - * pattern and their ancestors will be hidden from the output on the - * revision walk. - * - * A leading 'refs/' is implied if not present as well as a trailing - * '/ *' if the glob lacks '?', '*' or '['. - * - * @param walk the walker being used for the traversal - * @param glob the glob pattern references should match - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob); - -/** - * Hide the repository's HEAD - * - * @param walk the walker being used for the traversal - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk); - -/** - * Push the OID pointed to by a reference - * - * The reference must point to a commit. - * - * @param walk the walker being used for the traversal - * @param refname the reference to push - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname); - -/** - * Hide the OID pointed to by a reference - * - * The reference must point to a commit. - * - * @param walk the walker being used for the traversal - * @param refname the reference to hide - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname); - -/** - * Get the next commit from the revision walk. - * - * The initial call to this method is *not* blocking when - * iterating through a repo with a time-sorting mode. - * - * Iterating with Topological or inverted modes makes the initial - * call blocking to preprocess the commit list, but this block should be - * mostly unnoticeable on most repositories (topological preprocessing - * times at 0.3s on the git.git repo). - * - * The revision walker is reset when the walk is over. - * - * @param out Pointer where to store the oid of the next commit - * @param walk the walker to pop the commit from. - * @return 0 if the next commit was found; - * GIT_ITEROVER if there are no commits left to iterate - */ -GIT_EXTERN(int) git_revwalk_next(git_oid *out, git_revwalk *walk); - -/** - * Change the sorting mode when iterating through the - * repository's contents. - * - * Changing the sorting mode resets the walker. - * - * @param walk the walker being used for the traversal. - * @param sort_mode combination of GIT_SORT_XXX flags - */ -GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode); - -/** - * Free a revision walker previously allocated. - * - * @param walk traversal handle to close. If NULL nothing occurs. - */ -GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk); - -/** - * Return the repository on which this walker - * is operating. - * - * @param walk the revision walker - * @return the repository being walked - */ -GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/signature.h b/git2/include/git2/signature.h deleted file mode 100644 index 00d19de66..000000000 --- a/git2/include/git2/signature.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_signature_h__ -#define INCLUDE_git_signature_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/signature.h - * @brief Git signature creation - * @defgroup git_signature Git signature creation - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new action signature. - * - * Call `git_signature_free()` to free the data. - * - * Note: angle brackets ('<' and '>') characters are not allowed - * to be used in either the `name` or the `email` parameter. - * - * @param out new signature, in case of error NULL - * @param name name of the person - * @param email email of the person - * @param time time when the action happened - * @param offset timezone offset in minutes for the time - * @return 0 or an error code - */ -GIT_EXTERN(int) git_signature_new(git_signature **out, const char *name, const char *email, git_time_t time, int offset); - -/** - * Create a new action signature with a timestamp of 'now'. - * - * Call `git_signature_free()` to free the data. - * - * @param out new signature, in case of error NULL - * @param name name of the person - * @param email email of the person - * @return 0 or an error code - */ -GIT_EXTERN(int) git_signature_now(git_signature **out, const char *name, const char *email); - - -/** - * Create a copy of an existing signature. All internal strings are also - * duplicated. - * - * Call `git_signature_free()` to free the data. - * - * @param sig signature to duplicated - * @return a copy of sig, NULL on out of memory - */ -GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig); - -/** - * Free an existing signature. - * - * Because the signature is not an opaque structure, it is legal to free it - * manually, but be sure to free the "name" and "email" strings in addition - * to the structure itself. - * - * @param sig signature to free - */ -GIT_EXTERN(void) git_signature_free(git_signature *sig); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/stash.h b/git2/include/git2/stash.h deleted file mode 100644 index cf8bc9d4c..000000000 --- a/git2/include/git2/stash.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_stash_h__ -#define INCLUDE_git_stash_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/stash.h - * @brief Git stash management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -typedef enum { - GIT_STASH_DEFAULT = 0, - - /* All changes already added to the index - * are left intact in the working directory - */ - GIT_STASH_KEEP_INDEX = (1 << 0), - - /* All untracked files are also stashed and then - * cleaned up from the working directory - */ - GIT_STASH_INCLUDE_UNTRACKED = (1 << 1), - - /* All ignored files are also stashed and then - * cleaned up from the working directory - */ - GIT_STASH_INCLUDE_IGNORED = (1 << 2), -} git_stash_flags; - -/** - * Save the local modifications to a new stash. - * - * @param out Object id of the commit containing the stashed state. - * This commit is also the target of the direct reference refs/stash. - * - * @param repo The owning repository. - * - * @param stasher The identity of the person performing the stashing. - * - * @param message Optional description along with the stashed state. - * - * @param flags Flags to control the stashing process. (see GIT_STASH_* above) - * - * @return 0 on success, GIT_ENOTFOUND where there's nothing to stash, - * or error code. - */ -GIT_EXTERN(int) git_stash_save( - git_oid *out, - git_repository *repo, - git_signature *stasher, - const char *message, - unsigned int flags); - -/** - * When iterating over all the stashed states, callback that will be - * issued per entry. - * - * @param index The position within the stash list. 0 points to the - * most recent stashed state. - * - * @param message The stash message. - * - * @param stash_id The commit oid of the stashed state. - * - * @param payload Extra parameter to callback function. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -typedef int (*git_stash_cb)( - size_t index, - const char* message, - const git_oid *stash_id, - void *payload); - -/** - * Loop over all the stashed states and issue a callback for each one. - * - * If the callback returns a non-zero value, this will stop looping. - * - * @param repo Repository where to find the stash. - * - * @param callabck Callback to invoke per found stashed state. The most recent - * stash state will be enumerated first. - * - * @param payload Extra parameter to callback function. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_stash_foreach( - git_repository *repo, - git_stash_cb callback, - void *payload); - -/** - * Remove a single stashed state from the stash list. - * - * @param repo The owning repository. - * - * @param index The position within the stash list. 0 points to the - * most recent stashed state. - * - * @return 0 on success, or error code - */ - -GIT_EXTERN(int) git_stash_drop( - git_repository *repo, - size_t index); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/status.h b/git2/include/git2/status.h deleted file mode 100644 index d0c4a496d..000000000 --- a/git2/include/git2/status.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_status_h__ -#define INCLUDE_git_status_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/status.h - * @brief Git file status routines - * @defgroup git_status Git file status routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Status flags for a single file. - * - * A combination of these values will be returned to indicate the status of - * a file. Status compares the working directory, the index, and the - * current HEAD of the repository. The `GIT_STATUS_INDEX` set of flags - * represents the status of file in the index relative to the HEAD, and the - * `GIT_STATUS_WT` set of flags represent the status of the file in the - * working directory relative to the index. - */ -typedef enum { - GIT_STATUS_CURRENT = 0, - - GIT_STATUS_INDEX_NEW = (1u << 0), - GIT_STATUS_INDEX_MODIFIED = (1u << 1), - GIT_STATUS_INDEX_DELETED = (1u << 2), - GIT_STATUS_INDEX_RENAMED = (1u << 3), - GIT_STATUS_INDEX_TYPECHANGE = (1u << 4), - - GIT_STATUS_WT_NEW = (1u << 7), - GIT_STATUS_WT_MODIFIED = (1u << 8), - GIT_STATUS_WT_DELETED = (1u << 9), - GIT_STATUS_WT_TYPECHANGE = (1u << 10), - - GIT_STATUS_IGNORED = (1u << 14), -} git_status_t; - -/** - * Function pointer to receive status on individual files - * - * `path` is the relative path to the file from the root of the repository. - * - * `status_flags` is a combination of `git_status_t` values that apply. - * - * `payload` is the value you passed to the foreach function as payload. - */ -typedef int (*git_status_cb)( - const char *path, unsigned int status_flags, void *payload); - -/** - * Gather file statuses and run a callback for each one. - * - * The callback is passed the path of the file, the status (a combination of - * the `git_status_t` values above) and the `payload` data pointer passed - * into this function. - * - * If the callback returns a non-zero value, this function will stop looping - * and return GIT_EUSER. - * - * @param repo A repository object - * @param callback The function to call on each file - * @param payload Pointer to pass through to callback function - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_status_foreach( - git_repository *repo, - git_status_cb callback, - void *payload); - -/** - * For extended status, select the files on which to report status. - * - * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the - * rough equivalent of `git status --porcelain` where each file - * will receive a callback indicating its status in the index and - * in the workdir. - * - GIT_STATUS_SHOW_INDEX_ONLY will only make callbacks for index - * side of status. The status of the index contents relative to - * the HEAD will be given. - * - GIT_STATUS_SHOW_WORKDIR_ONLY will only make callbacks for the - * workdir side of status, reporting the status of workdir content - * relative to the index. - * - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR behaves like index-only - * followed by workdir-only, causing two callbacks to be issued - * per file (first index then workdir). This is slightly more - * efficient than making separate calls. This makes it easier to - * emulate the output of a plain `git status`. - */ -typedef enum { - GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0, - GIT_STATUS_SHOW_INDEX_ONLY = 1, - GIT_STATUS_SHOW_WORKDIR_ONLY = 2, - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR = 3, -} git_status_show_t; - -/** - * Flags to control status callbacks - * - * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should be made - * on untracked files. These will only be made if the workdir files are - * included in the status "show" option. - * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should get - * callbacks. Again, these callbacks will only be made if the workdir - * files are included in the status "show" option. Right now, there is - * no option to include all files in directories that are ignored - * completely. - * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback should be - * made even on unmodified files. - * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories which - * appear to be submodules should just be skipped over. - * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the contents of - * untracked directories should be included in the status. Normally if - * an entire directory is new, then just the top-level directory will be - * included (with a trailing slash on the entry name). Given this flag, - * the directory itself will not be included, but all the files in it - * will. - * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given path - * will be treated as a literal path, and not as a pathspec. - * - * Calling `git_status_foreach()` is like calling the extended version - * with: GIT_STATUS_OPT_INCLUDE_IGNORED, GIT_STATUS_OPT_INCLUDE_UNTRACKED, - * and GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS. - */ -typedef enum { - GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0), - GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1), - GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2), - GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3), - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4), - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1 << 5), -} git_status_opt_t; - -/** - * Options to control how `git_status_foreach_ext()` will issue callbacks. - * - * This structure is set so that zeroing it out will give you relatively - * sane defaults. - * - * The `show` value is one of the `git_status_show_t` constants that - * control which files to scan and in what order. - * - * The `flags` value is an OR'ed combination of the `git_status_opt_t` - * values above. - * - * The `pathspec` is an array of path patterns to match (using - * fnmatch-style matching), or just an array of paths to match exactly if - * `GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH` is specified in the flags. - */ -typedef struct { - unsigned int version; - git_status_show_t show; - unsigned int flags; - git_strarray pathspec; -} git_status_options; - -#define GIT_STATUS_OPTIONS_VERSION 1 -#define GIT_STATUS_OPTIONS_INIT {GIT_STATUS_OPTIONS_VERSION} - -/** - * Gather file status information and run callbacks as requested. - * - * This is an extended version of the `git_status_foreach()` API that - * allows for more granular control over which paths will be processed and - * in what order. See the `git_status_options` structure for details - * about the additional controls that this makes available. - * - * @param repo Repository object - * @param opts Status options structure - * @param callback The function to call on each file - * @param payload Pointer to pass through to callback function - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_status_foreach_ext( - git_repository *repo, - const git_status_options *opts, - git_status_cb callback, - void *payload); - -/** - * Get file status for a single file. - * - * This is not quite the same as calling `git_status_foreach_ext()` with - * the pathspec set to the specified path. - * - * @param status_flags The status value for the file - * @param repo A repository object - * @param path The file to retrieve status for, rooted at the repo's workdir - * @return 0 on success, GIT_ENOTFOUND if the file is not found in the HEAD, - * index, and work tree, GIT_EINVALIDPATH if `path` points at a folder, - * GIT_EAMBIGUOUS if "path" matches multiple files, -1 on other error. - */ -GIT_EXTERN(int) git_status_file( - unsigned int *status_flags, - git_repository *repo, - const char *path); - -/** - * Test if the ignore rules apply to a given file. - * - * This function checks the ignore rules to see if they would apply to the - * given file. This indicates if the file would be ignored regardless of - * whether the file is already in the index or committed to the repository. - * - * One way to think of this is if you were to do "git add ." on the - * directory containing the file, would it be added or not? - * - * @param ignored Boolean returning 0 if the file is not ignored, 1 if it is - * @param repo A repository object - * @param path The file to check ignores for, rooted at the repo's workdir. - * @return 0 if ignore rules could be processed for the file (regardless - * of whether it exists or not), or an error < 0 if they could not. - */ -GIT_EXTERN(int) git_status_should_ignore( - int *ignored, - git_repository *repo, - const char *path); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/strarray.h b/git2/include/git2/strarray.h deleted file mode 100644 index 6ea570c14..000000000 --- a/git2/include/git2/strarray.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_strarray_h__ -#define INCLUDE_git_strarray_h__ - -#include "common.h" - -/** - * @file git2/strarray.h - * @brief Git string array routines - * @defgroup git_strarray Git string array routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** Array of strings */ -typedef struct git_strarray { - char **strings; - size_t count; -} git_strarray; - -/** - * Close a string array object - * - * This method should be called on `git_strarray` objects where the strings - * array is allocated and contains allocated strings, such as what you - * would get from `git_strarray_copy()`. Not doing so, will result in a - * memory leak. - * - * This does not free the `git_strarray` itself, since the library will - * never allocate that object directly itself (it is more commonly embedded - * inside another struct or created on the stack). - * - * @param array git_strarray from which to free string data - */ -GIT_EXTERN(void) git_strarray_free(git_strarray *array); - -/** - * Copy a string array object from source to target. - * - * Note: target is overwritten and hence should be empty, - * otherwise its contents are leaked. - * - * @param tgt target - * @param src source - * @return 0 on success, < 0 on allocation failure - */ -GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src); - - -/** @} */ -GIT_END_DECL - -#endif - diff --git a/git2/include/git2/submodule.h b/git2/include/git2/submodule.h deleted file mode 100644 index 1abd33e79..000000000 --- a/git2/include/git2/submodule.h +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_submodule_h__ -#define INCLUDE_git_submodule_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/submodule.h - * @brief Git submodule management utilities - * @defgroup git_submodule Git submodule management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Opaque structure representing a submodule. - * - * Submodule support in libgit2 builds a list of known submodules and keeps - * it in the repository. The list is built from the .gitmodules file, the - * .git/config file, the index, and the HEAD tree. Items in the working - * directory that look like submodules (i.e. a git repo) but are not - * mentioned in those places won't be tracked. - */ -typedef struct git_submodule git_submodule; - -/** - * Values that could be specified for the update rule of a submodule. - * - * Use the DEFAULT value if you have altered the update value via - * `git_submodule_set_update()` and wish to reset to the original default. - */ -typedef enum { - GIT_SUBMODULE_UPDATE_DEFAULT = -1, - GIT_SUBMODULE_UPDATE_CHECKOUT = 0, - GIT_SUBMODULE_UPDATE_REBASE = 1, - GIT_SUBMODULE_UPDATE_MERGE = 2, - GIT_SUBMODULE_UPDATE_NONE = 3 -} git_submodule_update_t; - -/** - * Values that could be specified for how closely to examine the - * working directory when getting submodule status. - * - * Use the DEFUALT value if you have altered the ignore value via - * `git_submodule_set_ignore()` and wish to reset to the original value. - */ -typedef enum { - GIT_SUBMODULE_IGNORE_DEFAULT = -1, /* reset to default */ - GIT_SUBMODULE_IGNORE_NONE = 0, /* any change or untracked == dirty */ - GIT_SUBMODULE_IGNORE_UNTRACKED = 1, /* dirty if tracked files change */ - GIT_SUBMODULE_IGNORE_DIRTY = 2, /* only dirty if HEAD moved */ - GIT_SUBMODULE_IGNORE_ALL = 3 /* never dirty */ -} git_submodule_ignore_t; - -/** - * Return codes for submodule status. - * - * A combination of these flags will be returned to describe the status of a - * submodule. Depending on the "ignore" property of the submodule, some of - * the flags may never be returned because they indicate changes that are - * supposed to be ignored. - * - * Submodule info is contained in 4 places: the HEAD tree, the index, config - * files (both .git/config and .gitmodules), and the working directory. Any - * or all of those places might be missing information about the submodule - * depending on what state the repo is in. We consider all four places to - * build the combination of status flags. - * - * There are four values that are not really status, but give basic info - * about what sources of submodule data are available. These will be - * returned even if ignore is set to "ALL". - * - * * IN_HEAD - superproject head contains submodule - * * IN_INDEX - superproject index contains submodule - * * IN_CONFIG - superproject gitmodules has submodule - * * IN_WD - superproject workdir has submodule - * - * The following values will be returned so long as ignore is not "ALL". - * - * * INDEX_ADDED - in index, not in head - * * INDEX_DELETED - in head, not in index - * * INDEX_MODIFIED - index and head don't match - * * WD_UNINITIALIZED - workdir contains empty directory - * * WD_ADDED - in workdir, not index - * * WD_DELETED - in index, not workdir - * * WD_MODIFIED - index and workdir head don't match - * - * The following can only be returned if ignore is "NONE" or "UNTRACKED". - * - * * WD_INDEX_MODIFIED - submodule workdir index is dirty - * * WD_WD_MODIFIED - submodule workdir has modified files - * - * Lastly, the following will only be returned for ignore "NONE". - * - * * WD_UNTRACKED - wd contains untracked files - */ -typedef enum { - GIT_SUBMODULE_STATUS_IN_HEAD = (1u << 0), - GIT_SUBMODULE_STATUS_IN_INDEX = (1u << 1), - GIT_SUBMODULE_STATUS_IN_CONFIG = (1u << 2), - GIT_SUBMODULE_STATUS_IN_WD = (1u << 3), - GIT_SUBMODULE_STATUS_INDEX_ADDED = (1u << 4), - GIT_SUBMODULE_STATUS_INDEX_DELETED = (1u << 5), - GIT_SUBMODULE_STATUS_INDEX_MODIFIED = (1u << 6), - GIT_SUBMODULE_STATUS_WD_UNINITIALIZED = (1u << 7), - GIT_SUBMODULE_STATUS_WD_ADDED = (1u << 8), - GIT_SUBMODULE_STATUS_WD_DELETED = (1u << 9), - GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10), - GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11), - GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12), - GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13), -} git_submodule_status_t; - -#define GIT_SUBMODULE_STATUS_IS_UNMODIFIED(S) \ - (((S) & ~(GIT_SUBMODULE_STATUS_IN_HEAD | \ - GIT_SUBMODULE_STATUS_IN_INDEX | \ - GIT_SUBMODULE_STATUS_IN_CONFIG | \ - GIT_SUBMODULE_STATUS_IN_WD)) == 0) - -#define GIT_SUBMODULE_STATUS_IS_WD_DIRTY(S) \ - (((S) & (GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED | \ - GIT_SUBMODULE_STATUS_WD_WD_MODIFIED | \ - GIT_SUBMODULE_STATUS_WD_UNTRACKED)) != 0) - -/** - * Lookup submodule information by name or path. - * - * Given either the submodule name or path (they are usually the same), this - * returns a structure describing the submodule. - * - * There are two expected error scenarios: - * - * - The submodule is not mentioned in the HEAD, the index, and the config, - * but does "exist" in the working directory (i.e. there is a subdirectory - * that is a valid self-contained git repo). In this case, this function - * returns GIT_EEXISTS to indicate the the submodule exists but not in a - * state where a git_submodule can be instantiated. - * - The submodule is not mentioned in the HEAD, index, or config and the - * working directory doesn't contain a value git repo at that path. - * There may or may not be anything else at that path, but nothing that - * looks like a submodule. In this case, this returns GIT_ENOTFOUND. - * - * The submodule object is owned by the containing repo and will be freed - * when the repo is freed. The caller need not free the submodule. - * - * @param submodule Pointer to submodule description object pointer.. - * @param repo The repository. - * @param name The name of the submodule. Trailing slashes will be ignored. - * @return 0 on success, GIT_ENOTFOUND if submodule does not exist, - * GIT_EEXISTS if submodule exists in working directory only, -1 on - * other errors. - */ -GIT_EXTERN(int) git_submodule_lookup( - git_submodule **submodule, - git_repository *repo, - const char *name); - -/** - * Iterate over all tracked submodules of a repository. - * - * See the note on `git_submodule` above. This iterates over the tracked - * submodules as decribed therein. - * - * If you are concerned about items in the working directory that look like - * submodules but are not tracked, the diff API will generate a diff record - * for workdir items that look like submodules but are not tracked, showing - * them as added in the workdir. Also, the status API will treat the entire - * subdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item. - * - * @param repo The repository - * @param callback Function to be called with the name of each submodule. - * Return a non-zero value to terminate the iteration. - * @param payload Extra data to pass to callback - * @return 0 on success, -1 on error, or non-zero return value of callback - */ -GIT_EXTERN(int) git_submodule_foreach( - git_repository *repo, - int (*callback)(git_submodule *sm, const char *name, void *payload), - void *payload); - -/** - * Set up a new git submodule for checkout. - * - * This does "git submodule add" up to the fetch and checkout of the - * submodule contents. It preps a new submodule, creates an entry in - * .gitmodules and creates an empty initialized repository either at the - * given path in the working directory or in .git/modules with a gitlink - * from the working directory to the new repo. - * - * To fully emulate "git submodule add" call this function, then open the - * submodule repo and perform the clone step as needed. Lastly, call - * `git_submodule_add_finalize()` to wrap up adding the new submodule and - * .gitmodules to the index to be ready to commit. - * - * @param submodule The newly created submodule ready to open for clone - * @param repo Superproject repository to contain the new submodule - * @param url URL for the submodules remote - * @param path Path at which the submodule should be created - * @param use_gitlink Should workdir contain a gitlink to the repo in - * .git/modules vs. repo directly in workdir. - * @return 0 on success, GIT_EEXISTS if submodule already exists, - * -1 on other errors. - */ -GIT_EXTERN(int) git_submodule_add_setup( - git_submodule **submodule, - git_repository *repo, - const char *url, - const char *path, - int use_gitlink); - -/** - * Resolve the setup of a new git submodule. - * - * This should be called on a submodule once you have called add setup - * and done the clone of the submodule. This adds the .gitmodules file - * and the newly cloned submodule to the index to be ready to be committed - * (but doesn't actually do the commit). - * - * @param submodule The submodule to finish adding. - */ -GIT_EXTERN(int) git_submodule_add_finalize(git_submodule *submodule); - -/** - * Add current submodule HEAD commit to index of superproject. - * - * @param submodule The submodule to add to the index - * @param write_index Boolean if this should immediately write the index - * file. If you pass this as false, you will have to get the - * git_index and explicitly call `git_index_write()` on it to - * save the change. - * @return 0 on success, <0 on failure - */ -GIT_EXTERN(int) git_submodule_add_to_index( - git_submodule *submodule, - int write_index); - -/** - * Write submodule settings to .gitmodules file. - * - * This commits any in-memory changes to the submodule to the gitmodules - * file on disk. You may also be interested in `git_submodule_init()` which - * writes submodule info to ".git/config" (which is better for local changes - * to submodule settings) and/or `git_submodule_sync()` which writes - * settings about remotes to the actual submodule repository. - * - * @param submodule The submodule to write. - * @return 0 on success, <0 on failure. - */ -GIT_EXTERN(int) git_submodule_save(git_submodule *submodule); - -/** - * Get the containing repository for a submodule. - * - * This returns a pointer to the repository that contains the submodule. - * This is a just a reference to the repository that was passed to the - * original `git_submodule_lookup()` call, so if that repository has been - * freed, then this may be a dangling reference. - * - * @param submodule Pointer to submodule object - * @return Pointer to `git_repository` - */ -GIT_EXTERN(git_repository *) git_submodule_owner(git_submodule *submodule); - -/** - * Get the name of submodule. - * - * @param submodule Pointer to submodule object - * @return Pointer to the submodule name - */ -GIT_EXTERN(const char *) git_submodule_name(git_submodule *submodule); - -/** - * Get the path to the submodule. - * - * The path is almost always the same as the submodule name, but the - * two are actually not required to match. - * - * @param submodule Pointer to submodule object - * @return Pointer to the submodule path - */ -GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule); - -/** - * Get the URL for the submodule. - * - * @param submodule Pointer to submodule object - * @return Pointer to the submodule url - */ -GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule); - -/** - * Set the URL for the submodule. - * - * This sets the URL in memory for the submodule. This will be used for - * any following submodule actions while this submodule data is in memory. - * - * After calling this, you may wish to call `git_submodule_save()` to write - * the changes back to the ".gitmodules" file and `git_submodule_sync()` to - * write the changes to the checked out submodule repository. - * - * @param submodule Pointer to the submodule object - * @param url URL that should be used for the submodule - * @return 0 on success, <0 on failure - */ -GIT_EXTERN(int) git_submodule_set_url(git_submodule *submodule, const char *url); - -/** - * Get the OID for the submodule in the index. - * - * @param submodule Pointer to submodule object - * @return Pointer to git_oid or NULL if submodule is not in index. - */ -GIT_EXTERN(const git_oid *) git_submodule_index_id(git_submodule *submodule); - -/** - * Get the OID for the submodule in the current HEAD tree. - * - * @param submodule Pointer to submodule object - * @return Pointer to git_oid or NULL if submodule is not in the HEAD. - */ -GIT_EXTERN(const git_oid *) git_submodule_head_id(git_submodule *submodule); - -/** - * Get the OID for the submodule in the current working directory. - * - * This returns the OID that corresponds to looking up 'HEAD' in the checked - * out submodule. If there are pending changes in the index or anything - * else, this won't notice that. You should call `git_submodule_status()` - * for a more complete picture about the state of the working directory. - * - * @param submodule Pointer to submodule object - * @return Pointer to git_oid or NULL if submodule is not checked out. - */ -GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule); - -/** - * Get the ignore rule for the submodule. - * - * There are four ignore values: - * - * - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents - * of the submodule from a clean checkout to be dirty, including the - * addition of untracked files. This is the default if unspecified. - * - **GIT_SUBMODULE_IGNORE_UNTRACKED** examines the contents of the - * working tree (i.e. call `git_status_foreach()` on the submodule) but - * UNTRACKED files will not count as making the submodule dirty. - * - **GIT_SUBMODULE_IGNORE_DIRTY** means to only check if the HEAD of the - * submodule has moved for status. This is fast since it does not need to - * scan the working tree of the submodule at all. - * - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo. - * The working directory will be consider clean so long as there is a - * checked out version present. - */ -GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore( - git_submodule *submodule); - -/** - * Set the ignore rule for the submodule. - * - * This sets the ignore rule in memory for the submodule. This will be used - * for any following actions (such as `git_submodule_status()`) while the - * submodule is in memory. You should call `git_submodule_save()` if you - * want to persist the new ignore role. - * - * Calling this again with GIT_SUBMODULE_IGNORE_DEFAULT or calling - * `git_submodule_reload()` will revert the rule to the value that was in the - * original config. - * - * @return old value for ignore - */ -GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore( - git_submodule *submodule, - git_submodule_ignore_t ignore); - -/** - * Get the update rule for the submodule. - */ -GIT_EXTERN(git_submodule_update_t) git_submodule_update( - git_submodule *submodule); - -/** - * Set the update rule for the submodule. - * - * This sets the update rule in memory for the submodule. You should call - * `git_submodule_save()` if you want to persist the new update rule. - * - * Calling this again with GIT_SUBMODULE_UPDATE_DEFAULT or calling - * `git_submodule_reload()` will revert the rule to the value that was in the - * original config. - * - * @return old value for update - */ -GIT_EXTERN(git_submodule_update_t) git_submodule_set_update( - git_submodule *submodule, - git_submodule_update_t update); - -/** - * Read the fetchRecurseSubmodules rule for a submodule. - * - * This accesses the submodule..fetchRecurseSubmodules value for - * the submodule that controls fetching behavior for the submodule. - * - * Note that at this time, libgit2 does not honor this setting and the - * fetch functionality current ignores submodules. - * - * @return 0 if fetchRecurseSubmodules is false, 1 if true - */ -GIT_EXTERN(int) git_submodule_fetch_recurse_submodules( - git_submodule *submodule); - -/** - * Set the fetchRecurseSubmodules rule for a submodule. - * - * This sets the submodule..fetchRecurseSubmodules value for - * the submodule. You should call `git_submodule_save()` if you want - * to persist the new value. - * - * @param submodule The submodule to modify - * @param fetch_recurse_submodules Boolean value - * @return old value for fetchRecurseSubmodules - */ -GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules( - git_submodule *submodule, - int fetch_recurse_submodules); - -/** - * Copy submodule info into ".git/config" file. - * - * Just like "git submodule init", this copies information about the - * submodule into ".git/config". You can use the accessor functions - * above to alter the in-memory git_submodule object and control what - * is written to the config, overriding what is in .gitmodules. - * - * @param submodule The submodule to write into the superproject config - * @param overwrite By default, existing entries will not be overwritten, - * but setting this to true forces them to be updated. - * @return 0 on success, <0 on failure. - */ -GIT_EXTERN(int) git_submodule_init(git_submodule *submodule, int overwrite); - -/** - * Copy submodule remote info into submodule repo. - * - * This copies the information about the submodules URL into the checked out - * submodule config, acting like "git submodule sync". This is useful if - * you have altered the URL for the submodule (or it has been altered by a - * fetch of upstream changes) and you need to update your local repo. - */ -GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule); - -/** - * Open the repository for a submodule. - * - * This is a newly opened repository object. The caller is responsible for - * calling `git_repository_free()` on it when done. Multiple calls to this - * function will return distinct `git_repository` objects. This will only - * work if the submodule is checked out into the working directory. - * - * @param subrepo Pointer to the submodule repo which was opened - * @param submodule Submodule to be opened - * @return 0 on success, <0 if submodule repo could not be opened. - */ -GIT_EXTERN(int) git_submodule_open( - git_repository **repo, - git_submodule *submodule); - -/** - * Reread submodule info from config, index, and HEAD. - * - * Call this to reread cached submodule information for this submodule if - * you have reason to believe that it has changed. - */ -GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule); - -/** - * Reread all submodule info. - * - * Call this to reload all cached submodule information for the repo. - */ -GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo); - -/** - * Get the status for a submodule. - * - * This looks at a submodule and tries to determine the status. It - * will return a combination of the `GIT_SUBMODULE_STATUS` values above. - * How deeply it examines the working directory to do this will depend - * on the `git_submodule_ignore_t` value for the submodule - which can be - * set either temporarily or permanently with `git_submodule_set_ignore()`. - * - * @param status Combination of `GIT_SUBMODULE_STATUS` flags - * @param submodule Submodule for which to get status - * @return 0 on success, <0 on error - */ -GIT_EXTERN(int) git_submodule_status( - unsigned int *status, - git_submodule *submodule); - -/** - * Get the locations of submodule information. - * - * This is a bit like a very lightweight version of `git_submodule_status`. - * It just returns a made of the first four submodule status values (i.e. - * the ones like GIT_SUBMODULE_STATUS_IN_HEAD, etc) that tell you where the - * submodule data comes from (i.e. the HEAD commit, gitmodules file, etc.). - * This can be useful if you want to know if the submodule is present in the - * working directory at this point in time, etc. - * - * @param status Combination of first four `GIT_SUBMODULE_STATUS` flags - * @param submodule Submodule for which to get status - * @return 0 on success, <0 on error - */ -GIT_EXTERN(int) git_submodule_location( - unsigned int *location_status, - git_submodule *submodule); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/tag.h b/git2/include/git2/tag.h deleted file mode 100644 index 1ffeb0b4a..000000000 --- a/git2/include/git2/tag.h +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_tag_h__ -#define INCLUDE_git_tag_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" -#include "strarray.h" - -/** - * @file git2/tag.h - * @brief Git tag parsing routines - * @defgroup git_tag Git tag management - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a tag object from the repository. - * - * @param out pointer to the looked up tag - * @param repo the repo to use when locating the tag. - * @param id identity of the tag to locate. - * @return 0 or an error code - */ -GIT_INLINE(int) git_tag_lookup( - git_tag **out, git_repository *repo, const git_oid *id) -{ - return git_object_lookup( - (git_object **)out, repo, id, (git_otype)GIT_OBJ_TAG); -} - -/** - * Lookup a tag object from the repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param out pointer to the looked up tag - * @param repo the repo to use when locating the tag. - * @param id identity of the tag to locate. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_tag_lookup_prefix( - git_tag **out, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix( - (git_object **)out, repo, id, len, (git_otype)GIT_OBJ_TAG); -} - -/** - * Close an open tag - * - * You can no longer use the git_tag pointer after this call. - * - * IMPORTANT: You MUST call this method when you are through with a tag to - * release memory. Failure to do so will cause a memory leak. - * - * @param tag the tag to close - */ - -GIT_INLINE(void) git_tag_free(git_tag *tag) -{ - git_object_free((git_object *)tag); -} - - -/** - * Get the id of a tag. - * - * @param tag a previously loaded tag. - * @return object identity for the tag. - */ -GIT_EXTERN(const git_oid *) git_tag_id(const git_tag *tag); - -/** - * Get the tagged object of a tag - * - * This method performs a repository lookup for the - * given object and returns it - * - * @param target_out pointer where to store the target - * @param tag a previously loaded tag. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_target(git_object **target_out, const git_tag *tag); - -/** - * Get the OID of the tagged object of a tag - * - * @param tag a previously loaded tag. - * @return pointer to the OID - */ -GIT_EXTERN(const git_oid *) git_tag_target_id(const git_tag *tag); - -/** - * Get the type of a tag's tagged object - * - * @param tag a previously loaded tag. - * @return type of the tagged object - */ -GIT_EXTERN(git_otype) git_tag_target_type(const git_tag *tag); - -/** - * Get the name of a tag - * - * @param tag a previously loaded tag. - * @return name of the tag - */ -GIT_EXTERN(const char *) git_tag_name(const git_tag *tag); - -/** - * Get the tagger (author) of a tag - * - * @param tag a previously loaded tag. - * @return reference to the tag's author - */ -GIT_EXTERN(const git_signature *) git_tag_tagger(const git_tag *tag); - -/** - * Get the message of a tag - * - * @param tag a previously loaded tag. - * @return message of the tag - */ -GIT_EXTERN(const char *) git_tag_message(const git_tag *tag); - - -/** - * Create a new tag in the repository from an object - * - * A new reference will also be created pointing to - * this tag object. If `force` is true and a reference - * already exists with the given name, it'll be replaced. - * - * The message will not be cleaned up. This can be achieved - * through `git_message_prettify()`. - * - * The tag name will be checked for validity. You must avoid - * the characters '~', '^', ':', '\\', '?', '[', and '*', and the - * sequences ".." and "@{" which have special meaning to revparse. - * - * @param oid Pointer where to store the OID of the - * newly created tag. If the tag already exists, this parameter - * will be the oid of the existing tag, and the function will - * return a GIT_EEXISTS error code. - * - * @param repo Repository where to store the tag - * - * @param tag_name Name for the tag; this name is validated - * for consistency. It should also not conflict with an - * already existing tag name - * - * @param target Object to which this tag points. This object - * must belong to the given `repo`. - * - * @param tagger Signature of the tagger for this tag, and - * of the tagging time - * - * @param message Full message for this tag - * - * @param force Overwrite existing references - * - * @return 0 on success, GIT_EINVALIDSPEC or an error code - * A tag object is written to the ODB, and a proper reference - * is written in the /refs/tags folder, pointing to it - */ -GIT_EXTERN(int) git_tag_create( - git_oid *oid, - git_repository *repo, - const char *tag_name, - const git_object *target, - const git_signature *tagger, - const char *message, - int force); - -/** - * Create a new tag in the repository from a buffer - * - * @param oid Pointer where to store the OID of the newly created tag - * @param repo Repository where to store the tag - * @param buffer Raw tag data - * @param force Overwrite existing tags - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_tag_create_frombuffer( - git_oid *oid, - git_repository *repo, - const char *buffer, - int force); - -/** - * Create a new lightweight tag pointing at a target object - * - * A new direct reference will be created pointing to - * this target object. If `force` is true and a reference - * already exists with the given name, it'll be replaced. - * - * The tag name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param oid Pointer where to store the OID of the provided - * target object. If the tag already exists, this parameter - * will be filled with the oid of the existing pointed object - * and the function will return a GIT_EEXISTS error code. - * - * @param repo Repository where to store the lightweight tag - * - * @param tag_name Name for the tag; this name is validated - * for consistency. It should also not conflict with an - * already existing tag name - * - * @param target Object to which this tag points. This object - * must belong to the given `repo`. - * - * @param force Overwrite existing references - * - * @return 0 on success, GIT_EINVALIDSPEC or an error code - * A proper reference is written in the /refs/tags folder, - * pointing to the provided target object - */ -GIT_EXTERN(int) git_tag_create_lightweight( - git_oid *oid, - git_repository *repo, - const char *tag_name, - const git_object *target, - int force); - -/** - * Delete an existing tag reference. - * - * The tag name will be checked for validity. - * See `git_tag_create()` for rules about valid names. - * - * @param repo Repository where lives the tag - * - * @param tag_name Name of the tag to be deleted; - * this name is validated for consistency. - * - * @return 0 on success, GIT_EINVALIDSPEC or an error code - */ -GIT_EXTERN(int) git_tag_delete( - git_repository *repo, - const char *tag_name); - -/** - * Fill a list with all the tags in the Repository - * - * The string array will be filled with the names of the - * matching tags; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. - * - * @param tag_names Pointer to a git_strarray structure where - * the tag names will be stored - * @param repo Repository where to find the tags - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_list( - git_strarray *tag_names, - git_repository *repo); - -/** - * Fill a list with all the tags in the Repository - * which name match a defined pattern - * - * If an empty pattern is provided, all the tags - * will be returned. - * - * The string array will be filled with the names of the - * matching tags; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. - * - * @param tag_names Pointer to a git_strarray structure where - * the tag names will be stored - * @param pattern Standard fnmatch pattern - * @param repo Repository where to find the tags - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_list_match( - git_strarray *tag_names, - const char *pattern, - git_repository *repo); - - -typedef int (*git_tag_foreach_cb)(const char *name, git_oid *oid, void *payload); - -/** - * Call callback `cb' for each tag in the repository - * - * @param repo Repository - * @param callback Callback function - * @param payload Pointer to callback data (optional) - */ -GIT_EXTERN(int) git_tag_foreach( - git_repository *repo, - git_tag_foreach_cb callback, - void *payload); - - -/** - * Recursively peel a tag until a non tag git_object is found - * - * The retrieved `tag_target` object is owned by the repository - * and should be closed with the `git_object_free` method. - * - * @param tag_target_out Pointer to the peeled git_object - * @param tag The tag to be processed - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_peel( - git_object **tag_target_out, - const git_tag *tag); - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/threads.h b/git2/include/git2/threads.h deleted file mode 100644 index 11f89729a..000000000 --- a/git2/include/git2/threads.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_threads_h__ -#define INCLUDE_git_threads_h__ - -#include "common.h" - -/** - * @file git2/threads.h - * @brief Library level thread functions - * @defgroup git_thread Threading functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Init the threading system. - * - * If libgit2 has been built with GIT_THREADS - * on, this function must be called once before - * any other library functions. - * - * If libgit2 has been built without GIT_THREADS - * support, this function is a no-op. - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_threads_init(void); - -/** - * Shutdown the threading system. - * - * If libgit2 has been built with GIT_THREADS - * on, this function must be called before shutting - * down the library. - * - * If libgit2 has been built without GIT_THREADS - * support, this function is a no-op. - */ -GIT_EXTERN(void) git_threads_shutdown(void); - -/** @} */ -GIT_END_DECL -#endif - diff --git a/git2/include/git2/transport.h b/git2/include/git2/transport.h deleted file mode 100644 index fba5fb920..000000000 --- a/git2/include/git2/transport.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_transport_h__ -#define INCLUDE_git_transport_h__ - -#include "indexer.h" -#include "net.h" -#include "types.h" - -/** - * @file git2/transport.h - * @brief Git transport interfaces and functions - * @defgroup git_transport interfaces and functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/* - *** Begin interface for credentials acquisition *** - */ - -typedef enum { - /* git_cred_userpass_plaintext */ - GIT_CREDTYPE_USERPASS_PLAINTEXT = 1, -} git_credtype_t; - -/* The base structure for all credential types */ -typedef struct git_cred { - git_credtype_t credtype; - void (*free)( - struct git_cred *cred); -} git_cred; - -/* A plaintext username and password */ -typedef struct git_cred_userpass_plaintext { - git_cred parent; - char *username; - char *password; -} git_cred_userpass_plaintext; - -/** - * Creates a new plain-text username and password credential object. - * - * @param out The newly created credential object. - * @param username The username of the credential. - * @param password The password of the credential. - */ -GIT_EXTERN(int) git_cred_userpass_plaintext_new( - git_cred **out, - const char *username, - const char *password); - -/** - * Signature of a function which acquires a credential object. - * - * @param cred The newly created credential object. - * @param url The resource for which we are demanding a credential. - * @param allowed_types A bitmask stating which cred types are OK to return. - */ -typedef int (*git_cred_acquire_cb)( - git_cred **cred, - const char *url, - unsigned int allowed_types, - void *payload); - -/* - *** End interface for credentials acquisition *** - *** Begin base transport interface *** - */ - -typedef enum { - GIT_TRANSPORTFLAGS_NONE = 0, - /* If the connection is secured with SSL/TLS, the authenticity - * of the server certificate should not be verified. */ - GIT_TRANSPORTFLAGS_NO_CHECK_CERT = 1 -} git_transport_flags_t; - -typedef void (*git_transport_message_cb)(const char *str, int len, void *data); - -typedef struct git_transport { - unsigned int version; - /* Set progress and error callbacks */ - int (*set_callbacks)(struct git_transport *transport, - git_transport_message_cb progress_cb, - git_transport_message_cb error_cb, - void *payload); - - /* Connect the transport to the remote repository, using the given - * direction. */ - int (*connect)(struct git_transport *transport, - const char *url, - git_cred_acquire_cb cred_acquire_cb, - void *cred_acquire_payload, - int direction, - int flags); - - /* This function may be called after a successful call to connect(). The - * provided callback is invoked for each ref discovered on the remote - * end. */ - int (*ls)(struct git_transport *transport, - git_headlist_cb list_cb, - void *payload); - - /* Executes the push whose context is in the git_push object. */ - int (*push)(struct git_transport *transport, git_push *push); - - /* This function may be called after a successful call to connect(), when - * the direction is FETCH. The function performs a negotiation to calculate - * the wants list for the fetch. */ - int (*negotiate_fetch)(struct git_transport *transport, - git_repository *repo, - const git_remote_head * const *refs, - size_t count); - - /* This function may be called after a successful call to negotiate_fetch(), - * when the direction is FETCH. This function retrieves the pack file for - * the fetch from the remote end. */ - int (*download_pack)(struct git_transport *transport, - git_repository *repo, - git_transfer_progress *stats, - git_transfer_progress_callback progress_cb, - void *progress_payload); - - /* Checks to see if the transport is connected */ - int (*is_connected)(struct git_transport *transport); - - /* Reads the flags value previously passed into connect() */ - int (*read_flags)(struct git_transport *transport, int *flags); - - /* Cancels any outstanding transport operation */ - void (*cancel)(struct git_transport *transport); - - /* This function is the reverse of connect() -- it terminates the - * connection to the remote end. */ - int (*close)(struct git_transport *transport); - - /* Frees/destructs the git_transport object. */ - void (*free)(struct git_transport *transport); -} git_transport; - -#define GIT_TRANSPORT_VERSION 1 -#define GIT_TRANSPORT_INIT {GIT_TRANSPORT_VERSION} - -/** - * Function to use to create a transport from a URL. The transport database - * is scanned to find a transport that implements the scheme of the URI (i.e. - * git:// or http://) and a transport object is returned to the caller. - * - * @param out The newly created transport (out) - * @param owner The git_remote which will own this transport - * @param url The URL to connect to - * @return 0 or an error code - */ -GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url); - -/** - * Function which checks to see if a transport could be created for the - * given URL (i.e. checks to see if libgit2 has a transport that supports - * the given URL's scheme) - * - * @param url The URL to check - * @return Zero if the URL is not valid; nonzero otherwise - */ -GIT_EXTERN(int) git_transport_valid_url(const char *url); - -/* Signature of a function which creates a transport */ -typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param); - -/* Transports which come with libgit2 (match git_transport_cb). The expected - * value for "param" is listed in-line below. */ - -/** - * Create an instance of the dummy transport. - * - * @param out The newly created transport (out) - * @param owner The git_remote which will own this transport - * @param payload You must pass NULL for this parameter. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_transport_dummy( - git_transport **out, - git_remote *owner, - /* NULL */ void *payload); - -/** - * Create an instance of the local transport. - * - * @param out The newly created transport (out) - * @param owner The git_remote which will own this transport - * @param payload You must pass NULL for this parameter. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_transport_local( - git_transport **out, - git_remote *owner, - /* NULL */ void *payload); - -/** - * Create an instance of the smart transport. - * - * @param out The newly created transport (out) - * @param owner The git_remote which will own this transport - * @param payload A pointer to a git_smart_subtransport_definition - * @return 0 or an error code - */ -GIT_EXTERN(int) git_transport_smart( - git_transport **out, - git_remote *owner, - /* (git_smart_subtransport_definition *) */ void *payload); - -/* - *** End of base transport interface *** - *** Begin interface for subtransports for the smart transport *** - */ - -/* The smart transport knows how to speak the git protocol, but it has no - * knowledge of how to establish a connection between it and another endpoint, - * or how to move data back and forth. For this, a subtransport interface is - * declared, and the smart transport delegates this work to the subtransports. - * Three subtransports are implemented: git, http, and winhttp. (The http and - * winhttp transports each implement both http and https.) */ - -/* Subtransports can either be RPC = 0 (persistent connection) or RPC = 1 - * (request/response). The smart transport handles the differences in its own - * logic. The git subtransport is RPC = 0, while http and winhttp are both - * RPC = 1. */ - -/* Actions that the smart transport can ask - * a subtransport to perform */ -typedef enum { - GIT_SERVICE_UPLOADPACK_LS = 1, - GIT_SERVICE_UPLOADPACK = 2, - GIT_SERVICE_RECEIVEPACK_LS = 3, - GIT_SERVICE_RECEIVEPACK = 4, -} git_smart_service_t; - -struct git_smart_subtransport; - -/* A stream used by the smart transport to read and write data - * from a subtransport */ -typedef struct git_smart_subtransport_stream { - /* The owning subtransport */ - struct git_smart_subtransport *subtransport; - - int (*read)( - struct git_smart_subtransport_stream *stream, - char *buffer, - size_t buf_size, - size_t *bytes_read); - - int (*write)( - struct git_smart_subtransport_stream *stream, - const char *buffer, - size_t len); - - void (*free)( - struct git_smart_subtransport_stream *stream); -} git_smart_subtransport_stream; - -/* An implementation of a subtransport which carries data for the - * smart transport */ -typedef struct git_smart_subtransport { - int (* action)( - git_smart_subtransport_stream **out, - struct git_smart_subtransport *transport, - const char *url, - git_smart_service_t action); - - /* Subtransports are guaranteed a call to close() between - * calls to action(), except for the following two "natural" progressions - * of actions against a constant URL. - * - * 1. UPLOADPACK_LS -> UPLOADPACK - * 2. RECEIVEPACK_LS -> RECEIVEPACK */ - int (* close)(struct git_smart_subtransport *transport); - - void (* free)(struct git_smart_subtransport *transport); -} git_smart_subtransport; - -/* A function which creates a new subtransport for the smart transport */ -typedef int (*git_smart_subtransport_cb)( - git_smart_subtransport **out, - git_transport* owner); - -typedef struct git_smart_subtransport_definition { - /* The function to use to create the git_smart_subtransport */ - git_smart_subtransport_cb callback; - - /* True if the protocol is stateless; false otherwise. For example, - * http:// is stateless, but git:// is not. */ - unsigned rpc : 1; -} git_smart_subtransport_definition; - -/* Smart transport subtransports that come with libgit2 */ - -/** - * Create an instance of the http subtransport. This subtransport - * also supports https. On Win32, this subtransport may be implemented - * using the WinHTTP library. - * - * @param out The newly created subtransport - * @param owner The smart transport to own this subtransport - * @return 0 or an error code - */ -GIT_EXTERN(int) git_smart_subtransport_http( - git_smart_subtransport **out, - git_transport* owner); - -/** - * Create an instance of the git subtransport. - * - * @param out The newly created subtransport - * @param owner The smart transport to own this subtransport - * @return 0 or an error code - */ -GIT_EXTERN(int) git_smart_subtransport_git( - git_smart_subtransport **out, - git_transport* owner); - -/* - *** End interface for subtransports for the smart transport *** - */ - -/** @} */ -GIT_END_DECL -#endif diff --git a/git2/include/git2/tree.h b/git2/include/git2/tree.h deleted file mode 100644 index 7726a6599..000000000 --- a/git2/include/git2/tree.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_tree_h__ -#define INCLUDE_git_tree_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/tree.h - * @brief Git tree parsing, loading routines - * @defgroup git_tree Git tree parsing, loading routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a tree object from the repository. - * - * @param out Pointer to the looked up tree - * @param repo The repo to use when locating the tree. - * @param id Identity of the tree to locate. - * @return 0 or an error code - */ -GIT_INLINE(int) git_tree_lookup( - git_tree **out, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)out, repo, id, GIT_OBJ_TREE); -} - -/** - * Lookup a tree object from the repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param tree pointer to the looked up tree - * @param repo the repo to use when locating the tree. - * @param id identity of the tree to locate. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_tree_lookup_prefix( - git_tree **out, - git_repository *repo, - const git_oid *id, - size_t len) -{ - return git_object_lookup_prefix( - (git_object **)out, repo, id, len, GIT_OBJ_TREE); -} - -/** - * Close an open tree - * - * You can no longer use the git_tree pointer after this call. - * - * IMPORTANT: You MUST call this method when you stop using a tree to - * release memory. Failure to do so will cause a memory leak. - * - * @param tree The tree to close - */ -GIT_INLINE(void) git_tree_free(git_tree *tree) -{ - git_object_free((git_object *)tree); -} - -/** - * Get the id of a tree. - * - * @param tree a previously loaded tree. - * @return object identity for the tree. - */ -GIT_EXTERN(const git_oid *) git_tree_id(const git_tree *tree); - -/** - * Get the repository that contains the tree. - * - * @param tree A previously loaded tree. - * @return Repository that contains this tree. - */ -GIT_EXTERN(git_repository *) git_tree_owner(const git_tree *tree); - -/** - * Get the number of entries listed in a tree - * - * @param tree a previously loaded tree. - * @return the number of entries in the tree - */ -GIT_EXTERN(size_t) git_tree_entrycount(const git_tree *tree); - -/** - * Lookup a tree entry by its filename - * - * This returns a git_tree_entry that is owned by the git_tree. You don't - * have to free it, but you must not use it after the git_tree is released. - * - * @param tree a previously loaded tree. - * @param filename the filename of the desired entry - * @return the tree entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname( - git_tree *tree, const char *filename); - -/** - * Lookup a tree entry by its position in the tree - * - * This returns a git_tree_entry that is owned by the git_tree. You don't - * have to free it, but you must not use it after the git_tree is released. - * - * @param tree a previously loaded tree. - * @param idx the position in the entry list - * @return the tree entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex( - git_tree *tree, size_t idx); - -/** - * Lookup a tree entry by SHA value. - * - * This returns a git_tree_entry that is owned by the git_tree. You don't - * have to free it, but you must not use it after the git_tree is released. - * - * Warning: this must examine every entry in the tree, so it is not fast. - * - * @param tree a previously loaded tree. - * @param oid the sha being looked for - * @return the tree entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid( - const git_tree *tree, const git_oid *oid); - -/** - * Retrieve a tree entry contained in a tree or in any of its subtrees, - * given its relative path. - * - * Unlike the other lookup functions, the returned tree entry is owned by - * the user and must be freed explicitly with `git_tree_entry_free()`. - * - * @param out Pointer where to store the tree entry - * @param root Previously loaded tree which is the root of the relative path - * @param subtree_path Path to the contained entry - * @return 0 on success; GIT_ENOTFOUND if the path does not exist - */ -GIT_EXTERN(int) git_tree_entry_bypath( - git_tree_entry **out, - git_tree *root, - const char *path); - -/** - * Duplicate a tree entry - * - * Create a copy of a tree entry. The returned copy is owned by the user, - * and must be freed explicitly with `git_tree_entry_free()`. - * - * @param entry A tree entry to duplicate - * @return a copy of the original entry or NULL on error (alloc failure) - */ -GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry); - -/** - * Free a user-owned tree entry - * - * IMPORTANT: This function is only needed for tree entries owned by the - * user, such as the ones returned by `git_tree_entry_dup()` or - * `git_tree_entry_bypath()`. - * - * @param entry The entry to free - */ -GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry); - -/** - * Get the filename of a tree entry - * - * @param entry a tree entry - * @return the name of the file - */ -GIT_EXTERN(const char *) git_tree_entry_name(const git_tree_entry *entry); - -/** - * Get the id of the object pointed by the entry - * - * @param entry a tree entry - * @return the oid of the object - */ -GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry); - -/** - * Get the type of the object pointed by the entry - * - * @param entry a tree entry - * @return the type of the pointed object - */ -GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry); - -/** - * Get the UNIX file attributes of a tree entry - * - * @param entry a tree entry - * @return filemode as an integer - */ -GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry); - -/** - * Convert a tree entry to the git_object it points too. - * - * You must call `git_object_free()` on the object when you are done with it. - * - * @param object pointer to the converted object - * @param repo repository where to lookup the pointed object - * @param entry a tree entry - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tree_entry_to_object( - git_object **object_out, - git_repository *repo, - const git_tree_entry *entry); - -/** - * Create a new tree builder. - * - * The tree builder can be used to create or modify trees in memory and - * write them as tree objects to the database. - * - * If the `source` parameter is not NULL, the tree builder will be - * initialized with the entries of the given tree. - * - * If the `source` parameter is NULL, the tree builder will start with no - * entries and will have to be filled manually. - * - * @param out Pointer where to store the tree builder - * @param source Source tree to initialize the builder (optional) - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_treebuilder_create( - git_treebuilder **out, const git_tree *source); - -/** - * Clear all the entires in the builder - * - * @param bld Builder to clear - */ -GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld); - -/** - * Free a tree builder - * - * This will clear all the entries and free to builder. - * Failing to free the builder after you're done using it - * will result in a memory leak - * - * @param bld Builder to free - */ -GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld); - -/** - * Get an entry from the builder from its filename - * - * The returned entry is owned by the builder and should - * not be freed manually. - * - * @param bld Tree builder - * @param filename Name of the entry - * @return pointer to the entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_treebuilder_get( - git_treebuilder *bld, const char *filename); - -/** - * Add or update an entry to the builder - * - * Insert a new entry for `filename` in the builder with the - * given attributes. - * - * If an entry named `filename` already exists, its attributes - * will be updated with the given ones. - * - * The optional pointer `out` can be used to retrieve a pointer to - * the newly created/updated entry. Pass NULL if you do not need it. - * - * No attempt is being made to ensure that the provided oid points - * to an existing git object in the object database, nor that the - * attributes make sense regarding the type of the pointed at object. - * - * @param out Pointer to store the entry (optional) - * @param bld Tree builder - * @param filename Filename of the entry - * @param id SHA1 oid of the entry - * @param filemode Folder attributes of the entry. This parameter must - * be valued with one of the following entries: 0040000, 0100644, - * 0100755, 0120000 or 0160000. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_treebuilder_insert( - const git_tree_entry **out, - git_treebuilder *bld, - const char *filename, - const git_oid *id, - git_filemode_t filemode); - -/** - * Remove an entry from the builder by its filename - * - * @param bld Tree builder - * @param filename Filename of the entry to remove - */ -GIT_EXTERN(int) git_treebuilder_remove( - git_treebuilder *bld, const char *filename); - -typedef int (*git_treebuilder_filter_cb)( - const git_tree_entry *entry, void *payload); - -/** - * Filter the entries in the tree - * - * The `filter` callback will be called for each entry in the tree with a - * pointer to the entry and the provided `payload`; if the callback returns - * non-zero, the entry will be filtered (removed from the builder). - * - * @param bld Tree builder - * @param filter Callback to filter entries - * @param payload Extra data to pass to filter - */ -GIT_EXTERN(void) git_treebuilder_filter( - git_treebuilder *bld, - git_treebuilder_filter_cb filter, - void *payload); - -/** - * Write the contents of the tree builder as a tree object - * - * The tree builder will be written to the given `repo`, and its - * identifying SHA1 hash will be stored in the `id` pointer. - * - * @param id Pointer to store the OID of the newly written tree - * @param repo Repository in which to store the object - * @param bld Tree builder to write - * @return 0 or an error code - */ -GIT_EXTERN(int) git_treebuilder_write( - git_oid *id, git_repository *repo, git_treebuilder *bld); - - -/** Callback for the tree traversal method */ -typedef int (*git_treewalk_cb)( - const char *root, const git_tree_entry *entry, void *payload); - -/** Tree traversal modes */ -typedef enum { - GIT_TREEWALK_PRE = 0, /* Pre-order */ - GIT_TREEWALK_POST = 1, /* Post-order */ -} git_treewalk_mode; - -/** - * Traverse the entries in a tree and its subtrees in post or pre order. - * - * The entries will be traversed in the specified order, children subtrees - * will be automatically loaded as required, and the `callback` will be - * called once per entry with the current (relative) root for the entry and - * the entry data itself. - * - * If the callback returns a positive value, the passed entry will be - * skipped on the traversal (in pre mode). A negative value stops the walk. - * - * @param tree The tree to walk - * @param mode Traversal mode (pre or post-order) - * @param callback Function to call on each tree entry - * @param payload Opaque pointer to be passed on each callback - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tree_walk( - const git_tree *tree, - git_treewalk_mode mode, - git_treewalk_cb callback, - void *payload); - -/** @} */ - -GIT_END_DECL -#endif diff --git a/git2/include/git2/types.h b/git2/include/git2/types.h deleted file mode 100644 index c16bb8872..000000000 --- a/git2/include/git2/types.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_types_h__ -#define INCLUDE_git_types_h__ - -#include "common.h" - -/** - * @file git2/types.h - * @brief libgit2 base & compatibility types - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Cross-platform compatibility types for off_t / time_t - * - * NOTE: This needs to be in a public header so that both the library - * implementation and client applications both agree on the same types. - * Otherwise we get undefined behavior. - * - * Use the "best" types that each platform provides. Currently we truncate - * these intermediate representations for compatibility with the git ABI, but - * if and when it changes to support 64 bit types, our code will naturally - * adapt. - * NOTE: These types should match those that are returned by our internal - * stat() functions, for all platforms. - */ -#include -#ifdef __amigaos4__ -#include -#endif - -#if defined(_MSC_VER) - -typedef __int64 git_off_t; -typedef __time64_t git_time_t; - -#elif defined(__MINGW32__) - -typedef off64_t git_off_t; -typedef __time64_t git_time_t; - -#elif defined(__HAIKU__) - -typedef __haiku_std_int64 git_off_t; -typedef __haiku_std_int64 git_time_t; - -#else /* POSIX */ - -/* - * Note: Can't use off_t since if a client program includes - * before us (directly or indirectly), they'll get 32 bit off_t in their client - * app, even though /we/ define _FILE_OFFSET_BITS=64. - */ -typedef int64_t git_off_t; -typedef int64_t git_time_t; - -#endif - -/** Basic type (loose or packed) of any Git object. */ -typedef enum { - GIT_OBJ_ANY = -2, /**< Object can be any of the following */ - GIT_OBJ_BAD = -1, /**< Object is invalid. */ - GIT_OBJ__EXT1 = 0, /**< Reserved for future use. */ - GIT_OBJ_COMMIT = 1, /**< A commit object. */ - GIT_OBJ_TREE = 2, /**< A tree (directory listing) object. */ - GIT_OBJ_BLOB = 3, /**< A file revision object. */ - GIT_OBJ_TAG = 4, /**< An annotated tag object. */ - GIT_OBJ__EXT2 = 5, /**< Reserved for future use. */ - GIT_OBJ_OFS_DELTA = 6, /**< A delta, base is given by an offset. */ - GIT_OBJ_REF_DELTA = 7, /**< A delta, base is given by object id. */ -} git_otype; - -/** An open object database handle. */ -typedef struct git_odb git_odb; - -/** A custom backend in an ODB */ -typedef struct git_odb_backend git_odb_backend; - -/** An object read from the ODB */ -typedef struct git_odb_object git_odb_object; - -/** A stream to read/write from the ODB */ -typedef struct git_odb_stream git_odb_stream; - -/** A stream to write a packfile to the ODB */ -typedef struct git_odb_writepack git_odb_writepack; - -/** - * Representation of an existing git repository, - * including all its object contents - */ -typedef struct git_repository git_repository; - -/** Representation of a generic object in a repository */ -typedef struct git_object git_object; - -/** Representation of an in-progress walk through the commits in a repo */ -typedef struct git_revwalk git_revwalk; - -/** Parsed representation of a tag object. */ -typedef struct git_tag git_tag; - -/** In-memory representation of a blob object. */ -typedef struct git_blob git_blob; - -/** Parsed representation of a commit object. */ -typedef struct git_commit git_commit; - -/** Representation of each one of the entries in a tree object. */ -typedef struct git_tree_entry git_tree_entry; - -/** Representation of a tree object. */ -typedef struct git_tree git_tree; - -/** Constructor for in-memory trees */ -typedef struct git_treebuilder git_treebuilder; - -/** Memory representation of an index file. */ -typedef struct git_index git_index; - -/** Memory representation of a set of config files */ -typedef struct git_config git_config; - -/** Interface to access a configuration file */ -typedef struct git_config_backend git_config_backend; - -/** Representation of a reference log entry */ -typedef struct git_reflog_entry git_reflog_entry; - -/** Representation of a reference log */ -typedef struct git_reflog git_reflog; - -/** Representation of a git note */ -typedef struct git_note git_note; - -/** Representation of a git packbuilder */ -typedef struct git_packbuilder git_packbuilder; - -/** Time in a signature */ -typedef struct git_time { - git_time_t time; /** time in seconds from epoch */ - int offset; /** timezone offset, in minutes */ -} git_time; - -/** An action signature (e.g. for committers, taggers, etc) */ -typedef struct git_signature { - char *name; /** full name of the author */ - char *email; /** email of the author */ - git_time when; /** time when the action happened */ -} git_signature; - -/** In-memory representation of a reference. */ -typedef struct git_reference git_reference; - -/** Basic type of any Git reference. */ -typedef enum { - GIT_REF_INVALID = 0, /** Invalid reference */ - GIT_REF_OID = 1, /** A reference which points at an object id */ - GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */ - GIT_REF_PACKED = 4, - GIT_REF_HAS_PEEL = 8, - GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED, -} git_ref_t; - -/** Basic type of any Git branch. */ -typedef enum { - GIT_BRANCH_LOCAL = 1, - GIT_BRANCH_REMOTE = 2, -} git_branch_t; - -/** Valid modes for index and tree entries. */ -typedef enum { - GIT_FILEMODE_NEW = 0000000, - GIT_FILEMODE_TREE = 0040000, - GIT_FILEMODE_BLOB = 0100644, - GIT_FILEMODE_BLOB_EXECUTABLE = 0100755, - GIT_FILEMODE_LINK = 0120000, - GIT_FILEMODE_COMMIT = 0160000, -} git_filemode_t; - -typedef struct git_refspec git_refspec; -typedef struct git_remote git_remote; -typedef struct git_push git_push; - -typedef struct git_remote_head git_remote_head; -typedef struct git_remote_callbacks git_remote_callbacks; - -/** @} */ -GIT_END_DECL - -#endif diff --git a/git2/include/git2/version.h b/git2/include/git2/version.h deleted file mode 100644 index bc03e85d6..000000000 --- a/git2/include/git2/version.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_version_h__ -#define INCLUDE_git_version_h__ - -#define LIBGIT2_VERSION "0.17.0" -#define LIBGIT2_VER_MAJOR 0 -#define LIBGIT2_VER_MINOR 17 -#define LIBGIT2_VER_REVISION 0 - -#endif diff --git a/git2/libgit2.gypi b/git2/libgit2.gypi deleted file mode 100644 index 0494be661..000000000 --- a/git2/libgit2.gypi +++ /dev/null @@ -1,50 +0,0 @@ -{ - 'variables': { - 'includes_common': [ - 'git2/include/git2.h', - 'git2/include/git2/attr.h', - 'git2/include/git2/blob.h', - 'git2/include/git2/branch.h', - 'git2/include/git2/commit.h', - 'git2/include/git2/common.h', - 'git2/include/git2/config.h', - 'git2/include/git2/diff.h', - 'git2/include/git2/errors.h', - 'git2/include/git2/index.h', - 'git2/include/git2/indexer.h', - 'git2/include/git2/merge.h', - 'git2/include/git2/net.h', - 'git2/include/git2/notes.h', - 'git2/include/git2/object.h', - 'git2/include/git2/odb.h', - 'git2/include/git2/odb_backend.h', - 'git2/include/git2/oid.h', - 'git2/include/git2/reflog.h', - 'git2/include/git2/refs.h', - 'git2/include/git2/refspec.h', - 'git2/include/git2/remote.h', - 'git2/include/git2/repository.h', - 'git2/include/git2/revwalk.h', - 'git2/include/git2/signature.h', - 'git2/include/git2/status.h', - 'git2/include/git2/submodule.h', - 'git2/include/git2/tag.h', - 'git2/include/git2/threads.h', - 'git2/include/git2/tree.h', - 'git2/include/git2/types.h', - 'git2/include/git2/version.h', - 'git2/include/git2/checkout.h', - 'git2/include/git2/clone.h', - 'git2/include/git2/ignore.h', - 'git2/include/git2/message.h', - 'git2/include/git2/pack.h', - 'git2/include/git2/reset.h', - 'git2/include/git2/revparse.h', - 'git2/include/git2/strarray.h', - 'git2/include/git2/graph.h', - 'git2/include/git2/push.h', - 'git2/include/git2/stash.h', - 'git2/include/git2/transport.h', - ], - } -} diff --git a/native/atom_cef_render_process_handler.h b/native/atom_cef_render_process_handler.h index 973086245..96fe15a5c 100644 --- a/native/atom_cef_render_process_handler.h +++ b/native/atom_cef_render_process_handler.h @@ -16,17 +16,6 @@ class AtomCefRenderProcessHandler : public CefRenderProcessHandler { virtual bool OnProcessMessageReceived(CefRefPtr browser, CefProcessId source_process, CefRefPtr message) OVERRIDE; - virtual void OnWorkerContextCreated(int worker_id, - const CefString& url, - CefRefPtr context) OVERRIDE; - virtual void OnWorkerContextReleased(int worker_id, - const CefString& url, - CefRefPtr context) OVERRIDE; - virtual void OnWorkerUncaughtException(int worker_id, - const CefString& url, - CefRefPtr context, - CefRefPtr exception, - CefRefPtr stackTrace) OVERRIDE; void Reload(CefRefPtr browser); void Shutdown(CefRefPtr browser); @@ -37,4 +26,3 @@ class AtomCefRenderProcessHandler : public CefRenderProcessHandler { }; #endif // ATOM_CEF_RENDER_PROCESS_HANDLER_H_ - diff --git a/native/atom_cef_render_process_handler.mm b/native/atom_cef_render_process_handler.mm index d36a6c235..b3147478c 100644 --- a/native/atom_cef_render_process_handler.mm +++ b/native/atom_cef_render_process_handler.mm @@ -1,10 +1,6 @@ #import #import "native/v8_extensions/atom.h" #import "native/v8_extensions/native.h" -#import "native/v8_extensions/onig_reg_exp.h" -#import "native/v8_extensions/onig_scanner.h" -#import "native/v8_extensions/git.h" -#import "native/v8_extensions/tags.h" #import "native/message_translation.h" #import "path_watcher.h" #import "atom_cef_render_process_handler.h" @@ -25,27 +21,6 @@ void AtomCefRenderProcessHandler::OnContextReleased(CefRefPtr browse [PathWatcher removePathWatcherForContext:context]; } -void AtomCefRenderProcessHandler::OnWorkerContextCreated(int worker_id, - const CefString& url, - CefRefPtr context) { - InjectExtensionsIntoV8Context(context); -} - -void AtomCefRenderProcessHandler::OnWorkerContextReleased(int worker_id, - const CefString& url, - CefRefPtr context) { -} - -void AtomCefRenderProcessHandler::OnWorkerUncaughtException(int worker_id, - const CefString& url, - CefRefPtr context, - CefRefPtr exception, - CefRefPtr stackTrace) { - - std::string message = exception->GetMessage().ToString(); - NSLog(@"Exception throw in worker thread %s", message.c_str()); -} - bool AtomCefRenderProcessHandler::OnProcessMessageReceived(CefRefPtr browser, CefProcessId source_process, CefRefPtr message) { @@ -122,8 +97,4 @@ void AtomCefRenderProcessHandler::InjectExtensionsIntoV8Context(CefRefPtrCreateContextBinding(context); (new v8_extensions::Native())->CreateContextBinding(context); - (new v8_extensions::Git())->CreateContextBinding(context); - (new v8_extensions::OnigRegExp())->CreateContextBinding(context); - (new v8_extensions::OnigScanner())->CreateContextBinding(context); - (new v8_extensions::Tags())->CreateContextBinding(context); } diff --git a/native/atom_window_controller.h b/native/atom_window_controller.h index 09b7590c6..15e5983b9 100644 --- a/native/atom_window_controller.h +++ b/native/atom_window_controller.h @@ -6,6 +6,7 @@ class AtomCefClient; NSSplitView *_splitView; NSView *_devToolsView; NSView *_webView; + NSButton *_devButton; NSString *_bootstrapScript; NSString *_resourcePath; NSString *_pathToOpen; diff --git a/native/atom_window_controller.mm b/native/atom_window_controller.mm index 1d9acd5d2..957f84a4b 100644 --- a/native/atom_window_controller.mm +++ b/native/atom_window_controller.mm @@ -16,6 +16,7 @@ [_splitView release]; [_devToolsView release]; [_webView release]; + [_devButton release]; [_bootstrapScript release]; [_resourcePath release]; [_pathToOpen release]; @@ -26,26 +27,31 @@ [super dealloc]; } -- (id)initWithBootstrapScript:(NSString *)bootstrapScript background:(BOOL)background alwaysUseBundleResourcePath:(BOOL)alwaysUseBundleResourcePath { +- (id)initWithBootstrapScript:(NSString *)bootstrapScript background:(BOOL)background useBundleResourcePath:(BOOL)useBundleResourcePath { self = [super initWithWindowNibName:@"AtomWindow"]; _bootstrapScript = [bootstrapScript retain]; AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication]; - _resourcePath = [atomApplication.arguments objectForKey:@"resource-path"]; - if (!alwaysUseBundleResourcePath && !_resourcePath) { - NSString *defaultRepositoryPath = [@"~/github/atom" stringByStandardizingPath]; - if ([defaultRepositoryPath characterAtIndex:0] == '/') { - BOOL isDir = false; - BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:defaultRepositoryPath isDirectory:&isDir]; - if (isDir && exists) - _resourcePath = defaultRepositoryPath; - } - } - - if (alwaysUseBundleResourcePath || !_resourcePath) { + if (useBundleResourcePath) { _resourcePath = [[NSBundle bundleForClass:self.class] resourcePath]; } + else { + _resourcePath = [[atomApplication.arguments objectForKey:@"resource-path"] stringByStandardizingPath]; + if (!_resourcePath) { + NSString *defaultRepositoryPath = [@"~/github/atom" stringByStandardizingPath]; + if ([defaultRepositoryPath characterAtIndex:0] == '/') { + BOOL isDir = false; + BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:defaultRepositoryPath isDirectory:&isDir]; + if (isDir && exists) { + _resourcePath = defaultRepositoryPath; + } + else { + NSLog(@"Warning: No resource path specified and no directory exists at ~/github/atom"); + } + } + } + } if ([self isDevMode]) { [self displayDevIcon]; @@ -54,6 +60,36 @@ _resourcePath = [_resourcePath stringByStandardizingPath]; [_resourcePath retain]; + NSMutableArray *paths = [NSMutableArray arrayWithObjects: + @"src/stdlib", + @"src/app", + @"src/packages", + @"src", + @"vendor", + @"static", + @"node_modules", + nil]; + NSMutableArray *resourcePaths = [[NSMutableArray alloc] init]; + + if (_runningSpecs) { + [paths insertObject:@"benchmark" atIndex:0]; + [paths insertObject:@"spec" atIndex:0]; + NSString *fixturePackagesDirectory = [NSString stringWithFormat:@"%@/spec/fixtures/packages", _resourcePath]; + [resourcePaths addObject:fixturePackagesDirectory]; + } + + NSString *userPackagesDirectory = [@"~/.atom/packages" stringByStandardizingPath]; + [resourcePaths addObject:userPackagesDirectory]; + + for (int i = 0; i < paths.count; i++) { + NSString *fullPath = [NSString stringWithFormat:@"%@/%@", _resourcePath, [paths objectAtIndex:i]]; + [resourcePaths addObject:fullPath]; + } + [resourcePaths addObject:_resourcePath]; + + NSString *nodePath = [resourcePaths componentsJoinedByString:@":"]; + setenv("NODE_PATH", [nodePath UTF8String], TRUE); + if (!background) { [self setShouldCascadeWindows:NO]; [self setWindowFrameAutosaveName:@"AtomWindow"]; @@ -69,19 +105,19 @@ _pathToOpen = [path retain]; AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication]; BOOL useBundleResourcePath = [atomApplication.arguments objectForKey:@"dev"] == nil; - return [self initWithBootstrapScript:@"window-bootstrap" background:NO alwaysUseBundleResourcePath:useBundleResourcePath]; + return [self initWithBootstrapScript:@"window-bootstrap" background:NO useBundleResourcePath:useBundleResourcePath]; } - (id)initDevWithPath:(NSString *)path { _pathToOpen = [path retain]; - return [self initWithBootstrapScript:@"window-bootstrap" background:NO alwaysUseBundleResourcePath:false]; + return [self initWithBootstrapScript:@"window-bootstrap" background:NO useBundleResourcePath:false]; } - (id)initInBackground { AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication]; BOOL useBundleResourcePath = [atomApplication.arguments objectForKey:@"dev"] == nil; - [self initWithBootstrapScript:@"window-bootstrap" background:YES alwaysUseBundleResourcePath:useBundleResourcePath]; + [self initWithBootstrapScript:@"window-bootstrap" background:YES useBundleResourcePath:useBundleResourcePath]; [self.window setFrame:NSMakeRect(0, 0, 0, 0) display:NO]; [self.window setExcludedFromWindowsMenu:YES]; [self.window setCollectionBehavior:NSWindowCollectionBehaviorStationary]; @@ -91,13 +127,13 @@ - (id)initSpecsThenExit:(BOOL)exitWhenDone { _runningSpecs = true; _exitWhenDone = exitWhenDone; - return [self initWithBootstrapScript:@"spec-bootstrap" background:NO alwaysUseBundleResourcePath:NO]; + return [self initWithBootstrapScript:@"spec-bootstrap" background:NO useBundleResourcePath:NO]; } - (id)initBenchmarksThenExit:(BOOL)exitWhenDone { _runningSpecs = true; _exitWhenDone = exitWhenDone; - return [self initWithBootstrapScript:@"benchmark-bootstrap" background:NO alwaysUseBundleResourcePath:NO]; + return [self initWithBootstrapScript:@"benchmark-bootstrap" background:NO useBundleResourcePath:NO]; } - (void)addBrowserToView:(NSView *)view url:(const char *)url cefHandler:(CefRefPtr)cefClient { @@ -123,9 +159,10 @@ // have the correct initial size based on the frame's last stored size. // HACK: I hate this and want to place this code directly in windowDidLoad - (void)attachWebView { - NSURL *url = [[NSBundle bundleForClass:self.class] resourceURL]; NSMutableString *urlString = [NSMutableString string]; - [urlString appendString:[[url URLByAppendingPathComponent:@"static/index.html"] absoluteString]]; + + NSURL *indexUrl = [[NSURL alloc] initFileURLWithPath:[_resourcePath stringByAppendingPathComponent:@"static/index.html"]]; + [urlString appendString:[indexUrl absoluteString]]; [urlString appendFormat:@"?bootstrapScript=%@", [self encodeUrlParam:_bootstrapScript]]; [urlString appendFormat:@"&resourcePath=%@", [self encodeUrlParam:_resourcePath]]; if ([self isDevMode]) @@ -208,6 +245,16 @@ return YES; } +- (void)windowWillEnterFullScreen:(NSNotification *)notification { + if (_devButton) + [_devButton setHidden:YES]; +} + +- (void)windowDidExitFullScreen:(NSNotification *)notification { + if (_devButton) + [_devButton setHidden:NO]; +} + - (bool)isDevMode { NSString *bundleResourcePath = [[NSBundle bundleForClass:self.class] resourcePath]; return ![_resourcePath isEqualToString:bundleResourcePath]; @@ -224,55 +271,43 @@ break; } - NSButton *devButton = [[NSButton alloc] init]; - [devButton setTitle:@"\xF0\x9F\x92\x80"]; - devButton.autoresizingMask = NSViewMinXMargin | NSViewMinYMargin; - devButton.buttonType = NSMomentaryChangeButton; - devButton.bordered = NO; - [devButton sizeToFit]; - devButton.frame = NSMakeRect(fullScreenButton.frame.origin.x - devButton.frame.size.width - 5, fullScreenButton.frame.origin.y, devButton.frame.size.width, devButton.frame.size.height); + _devButton = [[NSButton alloc] init]; + [_devButton setTitle:@"\xF0\x9F\x92\x80"]; + _devButton.autoresizingMask = NSViewMinXMargin | NSViewMinYMargin; + _devButton.buttonType = NSMomentaryChangeButton; + _devButton.bordered = NO; + [_devButton sizeToFit]; + _devButton.frame = NSMakeRect(fullScreenButton.frame.origin.x - _devButton.frame.size.width - 5, fullScreenButton.frame.origin.y, _devButton.frame.size.width, _devButton.frame.size.height); - [[self.window.contentView superview] addSubview:devButton]; + [[self.window.contentView superview] addSubview:_devButton]; } - (void)populateBrowserSettings:(CefBrowserSettings &)settings { CefString(&settings.default_encoding) = "UTF-8"; - settings.remote_fonts_disabled = false; - settings.encoding_detector_enabled = false; - settings.javascript_disabled = false; - settings.javascript_open_windows_disallowed = false; - settings.javascript_close_windows_disallowed = false; - settings.javascript_access_clipboard_disallowed = false; - settings.dom_paste_disabled = true; - settings.caret_browsing_enabled = false; - settings.java_disabled = true; - settings.plugins_disabled = true; - settings.universal_access_from_file_urls_allowed = false; - settings.file_access_from_file_urls_allowed = false; - settings.web_security_disabled = true; - settings.xss_auditor_enabled = true; - settings.image_load_disabled = false; - settings.shrink_standalone_images_to_fit = false; - settings.site_specific_quirks_disabled = false; - settings.text_area_resize_disabled = false; - settings.page_cache_disabled = true; - settings.tab_to_links_disabled = true; - settings.hyperlink_auditing_disabled = true; - settings.user_style_sheet_enabled = false; - settings.author_and_user_styles_disabled = false; - settings.local_storage_disabled = false; - settings.databases_disabled = false; - settings.application_cache_disabled = false; - settings.webgl_disabled = false; - settings.accelerated_compositing_disabled = false; - settings.accelerated_layers_disabled = false; - settings.accelerated_video_disabled = false; - settings.accelerated_2d_canvas_disabled = false; -// settings.accelerated_painting_enabled = true; -// settings.accelerated_filters_enabled = true; - settings.accelerated_plugins_disabled = false; - settings.developer_tools_disabled = false; -// settings.fullscreen_enabled = true; + settings.remote_fonts = STATE_ENABLED; + settings.javascript = STATE_ENABLED; + settings.javascript_open_windows = STATE_ENABLED; + settings.javascript_close_windows = STATE_ENABLED; + settings.javascript_access_clipboard = STATE_ENABLED; + settings.javascript_dom_paste = STATE_DISABLED; + settings.caret_browsing = STATE_DISABLED; + settings.java = STATE_DISABLED; + settings.plugins = STATE_DISABLED; + settings.universal_access_from_file_urls = STATE_DISABLED; + settings.file_access_from_file_urls = STATE_DISABLED; + settings.web_security = STATE_DISABLED; + settings.image_loading = STATE_ENABLED; + settings.image_shrink_standalone_to_fit = STATE_DISABLED; + settings.text_area_resize = STATE_ENABLED; + settings.page_cache = STATE_DISABLED; + settings.tab_to_links = STATE_DISABLED; + settings.author_and_user_styles = STATE_ENABLED; + settings.local_storage = STATE_ENABLED; + settings.databases = STATE_ENABLED; + settings.application_cache = STATE_ENABLED; + settings.webgl = STATE_ENABLED; + settings.accelerated_compositing = STATE_ENABLED; + settings.developer_tools = STATE_ENABLED; } @end diff --git a/native/frameworks/CocoaOniguruma.framework/CocoaOniguruma b/native/frameworks/CocoaOniguruma.framework/CocoaOniguruma deleted file mode 100755 index 3799f6f6b..000000000 Binary files a/native/frameworks/CocoaOniguruma.framework/CocoaOniguruma and /dev/null differ diff --git a/native/frameworks/CocoaOniguruma.framework/Headers/OnigRegexp.h b/native/frameworks/CocoaOniguruma.framework/Headers/OnigRegexp.h deleted file mode 100644 index 84f24b46d..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Headers/OnigRegexp.h +++ /dev/null @@ -1,91 +0,0 @@ -// CocoaOniguruma is copyrighted free software by Satoshi Nakagawa . -// You can redistribute it and/or modify it under the new BSD license. - -#import -#import "oniguruma.h" -#import "OnigRegexpUtility.h" - - -@class OnigResult; - -typedef enum { - OnigOptionNone = ONIG_OPTION_NONE, - OnigOptionIgnorecase = ONIG_OPTION_IGNORECASE, - OnigOptionExtend = ONIG_OPTION_EXTEND, - OnigOptionMultiline = ONIG_OPTION_MULTILINE, - OnigOptionSingleline = ONIG_OPTION_SINGLELINE, - OnigOptionFindLongest = ONIG_OPTION_FIND_LONGEST, - OnigOptionFindNotEmpty = ONIG_OPTION_FIND_NOT_EMPTY, - OnigOptionNegateSingleLine = ONIG_OPTION_NEGATE_SINGLELINE, - OnigOptionDontCaptureGroup = ONIG_OPTION_DONT_CAPTURE_GROUP, - OnigOptionCaptureGroup = ONIG_OPTION_CAPTURE_GROUP, - - /* options (search time) */ - OnigOptionNotbol = ONIG_OPTION_NOTBOL, - OnigOptionNoteol = ONIG_OPTION_NOTEOL, - OnigOptionPosixRegion = ONIG_OPTION_POSIX_REGION, - OnigOptionMaxbit = ONIG_OPTION_MAXBIT -} OnigOption; - -@interface OnigRegexp : NSObject -{ - regex_t* _entity; - NSString* _expression; -} - -+ (OnigRegexp*)compile:(NSString*)expression; -+ (OnigRegexp*)compile:(NSString*)expression error:(NSError **)error; -+ (OnigRegexp*)compileIgnorecase:(NSString*)expression; -+ (OnigRegexp*)compileIgnorecase:(NSString*)expression error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline extended:(BOOL)extended; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline extended:(BOOL)extended error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression options:(OnigOption)options; -+ (OnigRegexp*)compile:(NSString*)expression options:(OnigOption)options error:(NSError **)error; - -- (OnigResult*)search:(NSString*)target; -- (OnigResult*)search:(NSString*)target start:(int)start; -- (OnigResult*)search:(NSString*)target start:(int)start end:(int)end; -- (OnigResult*)search:(NSString*)target range:(NSRange)range; - -- (OnigResult*)match:(NSString*)target; -- (OnigResult*)match:(NSString*)target start:(int)start; - -- (NSUInteger)captureCount; -- (NSString*)expression; - -@end - - -@interface OnigResult : NSObject -{ - OnigRegexp* _expression; - OnigRegion* _region; - NSString* _target; - NSMutableArray* _captureNames; -} - -- (NSString*)target; - -- (int)count; -- (NSString*)stringAt:(int)index; -- (NSArray*)strings; -- (NSRange)rangeAt:(int)index; -- (int)locationAt:(int)index; -- (int)lengthAt:(int)index; - -- (NSString*)body; -- (NSRange)bodyRange; - -- (NSString*)preMatch; -- (NSString*)postMatch; - -// named capture support -- (NSArray*)captureNames; -- (int)indexForName:(NSString*)name; -- (NSIndexSet*)indexesForName:(NSString*)name; -- (NSString*)stringForName:(NSString*)name; -- (NSArray*)stringsForName:(NSString*)name; - -@end diff --git a/native/frameworks/CocoaOniguruma.framework/Headers/OnigRegexpUtility.h b/native/frameworks/CocoaOniguruma.framework/Headers/OnigRegexpUtility.h deleted file mode 100644 index 245ebae3d..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Headers/OnigRegexpUtility.h +++ /dev/null @@ -1,57 +0,0 @@ -// CocoaOniguruma is copyrighted free software by Satoshi Nakagawa . -// You can redistribute it and/or modify it under the new BSD license. - -#import -#import "oniguruma.h" -#import "OnigRegexp.h" - - -@class OnigRegexp; -@class OnigResult; - - -@interface NSString (OnigRegexpUtility) - -// pattern is OnigRegexp or NSString - -- (NSRange)rangeOfRegexp:(id)pattern; - -// based on ruby's split - -- (NSArray*)split; -- (NSArray*)splitByRegexp:(id)pattern; -- (NSArray*)splitByRegexp:(id)pattern limit:(int)limit; - -// based on ruby's gsub - -- (NSString*)replaceByRegexp:(id)pattern with:(NSString*)string; -- (NSString*)replaceAllByRegexp:(id)pattern with:(NSString*)string; - -- (NSString*)replaceByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; -- (NSString*)replaceAllByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; - -#if defined(NS_BLOCKS_AVAILABLE) -- (NSString*)replaceByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -- (NSString*)replaceAllByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -#endif - -@end - - -@interface NSMutableString (OnigRegexpUtility) - -// pattern is OnigRegexp or NSString - -// based on ruby's gsub - -- (NSMutableString*)replaceByRegexp:(id)pattern with:(NSString*)string; -- (NSMutableString*)replaceAllByRegexp:(id)pattern with:(NSString*)string; - -- (NSMutableString*)replaceByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; -- (NSMutableString*)replaceAllByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; - -#if defined(NS_BLOCKS_AVAILABLE) -- (NSMutableString*)replaceByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -- (NSMutableString*)replaceAllByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -#endif -@end diff --git a/native/frameworks/CocoaOniguruma.framework/Headers/oniguruma.h b/native/frameworks/CocoaOniguruma.framework/Headers/oniguruma.h deleted file mode 100644 index 8c6322c9b..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Headers/oniguruma.h +++ /dev/null @@ -1,770 +0,0 @@ -#ifndef ONIGURUMA_H -#define ONIGURUMA_H -/********************************************************************** - oniguruma.h - Oniguruma (regular expression library) -**********************************************************************/ -/*- - * Copyright (c) 2002-2009 K.Kosako - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define ONIGURUMA -#define ONIGURUMA_VERSION_MAJOR 5 -#define ONIGURUMA_VERSION_MINOR 9 -#define ONIGURUMA_VERSION_TEENY 2 - -#ifdef __cplusplus -# ifndef HAVE_PROTOTYPES -# define HAVE_PROTOTYPES 1 -# endif -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -/* escape Mac OS X/Xcode 2.4/gcc 4.0.1 problem */ -#if defined(__APPLE__) && defined(__GNUC__) && __GNUC__ >= 4 -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -#ifdef HAVE_STDARG_H -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -#ifndef P_ -#if defined(__STDC__) || defined(_WIN32) -# define P_(args) args -#else -# define P_(args) () -#endif -#endif - -#ifndef PV_ -#ifdef HAVE_STDARG_PROTOTYPES -# define PV_(args) args -#else -# define PV_(args) () -#endif -#endif - -#ifndef ONIG_EXTERN -#if defined(_WIN32) && !defined(__GNUC__) -#if defined(EXPORT) || defined(RUBY_EXPORT) -#define ONIG_EXTERN extern __declspec(dllexport) -#else -#define ONIG_EXTERN extern __declspec(dllimport) -#endif -#endif -#endif - -#ifndef ONIG_EXTERN -#define ONIG_EXTERN extern -#endif - -/* PART: character encoding */ - -#ifndef ONIG_ESCAPE_UCHAR_COLLISION -#define UChar OnigUChar -#endif - -typedef unsigned char OnigUChar; -typedef unsigned long OnigCodePoint; -typedef unsigned int OnigCtype; -typedef unsigned int OnigDistance; - -#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0) - -typedef unsigned int OnigCaseFoldType; /* case fold flag */ - -ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag; - -/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA (1<<1) */ -/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH (1<<2) */ -#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20) -#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30) - -#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR -#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag - - -#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3 -#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13 -/* 13 => Unicode:0x1ffc */ - -/* code range */ -#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0]) -#define ONIGENC_CODE_RANGE_FROM(range,i) range[((i)*2) + 1] -#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2] - -typedef struct { - int byte_len; /* argument(original) character(s) byte length */ - int code_len; /* number of code */ - OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN]; -} OnigCaseFoldCodeItem; - -typedef struct { - OnigCodePoint esc; - OnigCodePoint anychar; - OnigCodePoint anytime; - OnigCodePoint zero_or_one_time; - OnigCodePoint one_or_more_time; - OnigCodePoint anychar_anytime; -} OnigMetaCharTableType; - -typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg); - -typedef struct OnigEncodingTypeST { - int (*mbc_enc_len)(const OnigUChar* p); - const char* name; - int max_enc_len; - int min_enc_len; - int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end); - OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end); - int (*code_to_mbclen)(OnigCodePoint code); - int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf); - int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to); - int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg); - int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[]); - int (*property_name_to_ctype)(struct OnigEncodingTypeST* enc, OnigUChar* p, OnigUChar* end); - int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype); - int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[]); - OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p); - int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end); -} OnigEncodingType; - -typedef OnigEncodingType* OnigEncoding; - -ONIG_EXTERN OnigEncodingType OnigEncodingASCII; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_BE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_LE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_BE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_LE; - -#define ONIG_ENCODING_ASCII (&OnigEncodingASCII) -#define ONIG_ENCODING_UTF16_BE (&OnigEncodingUTF16_BE) -#define ONIG_ENCODING_UTF16_LE (&OnigEncodingUTF16_LE) -#define ONIG_ENCODING_UTF32_BE (&OnigEncodingUTF32_BE) -#define ONIG_ENCODING_UTF32_LE (&OnigEncodingUTF32_LE) - -#define ONIG_ENCODING_UNDEF ((OnigEncoding )0) - - -/* work size */ -#define ONIGENC_CODE_TO_MBC_MAXLEN 7 -#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18 -/* 18: 6(max-byte) * 3(case-fold chars) */ - -/* character types */ -#define ONIGENC_CTYPE_NEWLINE 0 -#define ONIGENC_CTYPE_ALPHA 1 -#define ONIGENC_CTYPE_BLANK 2 -#define ONIGENC_CTYPE_CNTRL 3 -#define ONIGENC_CTYPE_DIGIT 4 -#define ONIGENC_CTYPE_GRAPH 5 -#define ONIGENC_CTYPE_LOWER 6 -#define ONIGENC_CTYPE_PRINT 7 -#define ONIGENC_CTYPE_PUNCT 8 -#define ONIGENC_CTYPE_SPACE 9 -#define ONIGENC_CTYPE_UPPER 10 -#define ONIGENC_CTYPE_XDIGIT 11 -#define ONIGENC_CTYPE_WORD 12 -#define ONIGENC_CTYPE_ALNUM 13 /* alpha || digit */ -#define ONIGENC_CTYPE_ASCII 14 -#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII - - -#define onig_enc_len(enc,p,end) ONIGENC_MBC_ENC_LEN(enc,p) - -#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF) -#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1) -#define ONIGENC_IS_MBC_HEAD(enc,p) (ONIGENC_MBC_ENC_LEN(enc,p) != 1) -#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128) -#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128) -#define ONIGENC_IS_MBC_WORD(enc,s,end) \ - ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end)) - - -#define ONIGENC_NAME(enc) ((enc)->name) - -#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \ - (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf) -#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \ - (enc)->is_allowed_reverse_match(s,end) -#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \ - (enc)->left_adjust_char_head(start, s) -#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \ - (enc)->apply_all_case_fold(case_fold_flag,f,arg) -#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \ - (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs) -#define ONIGENC_STEP_BACK(enc,start,s,n) \ - onigenc_step_back((enc),(start),(s),(n)) - -#define ONIGENC_MBC_ENC_LEN(enc,p) (enc)->mbc_enc_len(p) -#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len) -#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc) -#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len) -#define ONIGENC_IS_MBC_NEWLINE(enc,p,end) (enc)->is_mbc_newline((p),(end)) -#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end)) -#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code) -#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf) -#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \ - (enc)->property_name_to_ctype(enc,p,end) - -#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype) - -#define ONIGENC_IS_CODE_NEWLINE(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE) -#define ONIGENC_IS_CODE_GRAPH(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH) -#define ONIGENC_IS_CODE_PRINT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT) -#define ONIGENC_IS_CODE_ALNUM(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM) -#define ONIGENC_IS_CODE_ALPHA(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA) -#define ONIGENC_IS_CODE_LOWER(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER) -#define ONIGENC_IS_CODE_UPPER(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER) -#define ONIGENC_IS_CODE_CNTRL(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL) -#define ONIGENC_IS_CODE_PUNCT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT) -#define ONIGENC_IS_CODE_SPACE(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE) -#define ONIGENC_IS_CODE_BLANK(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK) -#define ONIGENC_IS_CODE_DIGIT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT) -#define ONIGENC_IS_CODE_XDIGIT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT) -#define ONIGENC_IS_CODE_WORD(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD) - -#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \ - (enc)->get_ctype_code_range(ctype,sbout,ranges) - -ONIG_EXTERN -OnigUChar* onigenc_step_back P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, int n)); - - -/* encoding API */ -ONIG_EXTERN -int onigenc_init P_((void)); -ONIG_EXTERN -int onigenc_set_default_encoding P_((OnigEncoding enc)); -ONIG_EXTERN -OnigEncoding onigenc_get_default_encoding P_((void)); -ONIG_EXTERN -void onigenc_set_default_caseconv_table P_((const OnigUChar* table)); -ONIG_EXTERN -OnigUChar* onigenc_get_right_adjust_char_head_with_prev P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar** prev)); -ONIG_EXTERN -OnigUChar* onigenc_get_prev_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -OnigUChar* onigenc_get_left_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -OnigUChar* onigenc_get_right_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -int onigenc_strlen P_((OnigEncoding enc, const OnigUChar* p, const OnigUChar* end)); -ONIG_EXTERN -int onigenc_strlen_null P_((OnigEncoding enc, const OnigUChar* p)); -ONIG_EXTERN -int onigenc_str_bytelen_null P_((OnigEncoding enc, const OnigUChar* p)); - - - -/* PART: regular expression */ - -/* config parameters */ -#define ONIG_NREGION 10 -#define ONIG_MAX_BACKREF_NUM 1000 -#define ONIG_MAX_REPEAT_NUM 100000 -#define ONIG_MAX_MULTI_BYTE_RANGES_NUM 10000 -/* constants */ -#define ONIG_MAX_ERROR_MESSAGE_LEN 90 - -typedef unsigned int OnigOptionType; - -#define ONIG_OPTION_DEFAULT ONIG_OPTION_NONE - -/* options */ -#define ONIG_OPTION_NONE 0U -#define ONIG_OPTION_IGNORECASE 1U -#define ONIG_OPTION_EXTEND (ONIG_OPTION_IGNORECASE << 1) -#define ONIG_OPTION_MULTILINE (ONIG_OPTION_EXTEND << 1) -#define ONIG_OPTION_SINGLELINE (ONIG_OPTION_MULTILINE << 1) -#define ONIG_OPTION_FIND_LONGEST (ONIG_OPTION_SINGLELINE << 1) -#define ONIG_OPTION_FIND_NOT_EMPTY (ONIG_OPTION_FIND_LONGEST << 1) -#define ONIG_OPTION_NEGATE_SINGLELINE (ONIG_OPTION_FIND_NOT_EMPTY << 1) -#define ONIG_OPTION_DONT_CAPTURE_GROUP (ONIG_OPTION_NEGATE_SINGLELINE << 1) -#define ONIG_OPTION_CAPTURE_GROUP (ONIG_OPTION_DONT_CAPTURE_GROUP << 1) -/* options (search time) */ -#define ONIG_OPTION_NOTBOL (ONIG_OPTION_CAPTURE_GROUP << 1) -#define ONIG_OPTION_NOTEOL (ONIG_OPTION_NOTBOL << 1) -#define ONIG_OPTION_POSIX_REGION (ONIG_OPTION_NOTEOL << 1) -#define ONIG_OPTION_MAXBIT ONIG_OPTION_POSIX_REGION /* limit */ - -#define ONIG_OPTION_ON(options,regopt) ((options) |= (regopt)) -#define ONIG_OPTION_OFF(options,regopt) ((options) &= ~(regopt)) -#define ONIG_IS_OPTION_ON(options,option) ((options) & (option)) - -/* syntax */ -typedef struct { - unsigned int op; - unsigned int op2; - unsigned int behavior; - OnigOptionType options; /* default option */ - OnigMetaCharTableType meta_char_table; -} OnigSyntaxType; - -ONIG_EXTERN OnigSyntaxType OnigSyntaxASIS; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixBasic; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixExtended; -ONIG_EXTERN OnigSyntaxType OnigSyntaxEmacs; -ONIG_EXTERN OnigSyntaxType OnigSyntaxGrep; -ONIG_EXTERN OnigSyntaxType OnigSyntaxGnuRegex; -ONIG_EXTERN OnigSyntaxType OnigSyntaxJava; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl_NG; -ONIG_EXTERN OnigSyntaxType OnigSyntaxRuby; - -/* predefined syntaxes (see regsyntax.c) */ -#define ONIG_SYNTAX_ASIS (&OnigSyntaxASIS) -#define ONIG_SYNTAX_POSIX_BASIC (&OnigSyntaxPosixBasic) -#define ONIG_SYNTAX_POSIX_EXTENDED (&OnigSyntaxPosixExtended) -#define ONIG_SYNTAX_EMACS (&OnigSyntaxEmacs) -#define ONIG_SYNTAX_GREP (&OnigSyntaxGrep) -#define ONIG_SYNTAX_GNU_REGEX (&OnigSyntaxGnuRegex) -#define ONIG_SYNTAX_JAVA (&OnigSyntaxJava) -#define ONIG_SYNTAX_PERL (&OnigSyntaxPerl) -#define ONIG_SYNTAX_PERL_NG (&OnigSyntaxPerl_NG) -#define ONIG_SYNTAX_RUBY (&OnigSyntaxRuby) - -/* default syntax */ -ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax; -#define ONIG_SYNTAX_DEFAULT OnigDefaultSyntax - -/* syntax (operators) */ -#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS (1U<<0) -#define ONIG_SYN_OP_DOT_ANYCHAR (1U<<1) /* . */ -#define ONIG_SYN_OP_ASTERISK_ZERO_INF (1U<<2) /* * */ -#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF (1U<<3) -#define ONIG_SYN_OP_PLUS_ONE_INF (1U<<4) /* + */ -#define ONIG_SYN_OP_ESC_PLUS_ONE_INF (1U<<5) -#define ONIG_SYN_OP_QMARK_ZERO_ONE (1U<<6) /* ? */ -#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE (1U<<7) -#define ONIG_SYN_OP_BRACE_INTERVAL (1U<<8) /* {lower,upper} */ -#define ONIG_SYN_OP_ESC_BRACE_INTERVAL (1U<<9) /* \{lower,upper\} */ -#define ONIG_SYN_OP_VBAR_ALT (1U<<10) /* | */ -#define ONIG_SYN_OP_ESC_VBAR_ALT (1U<<11) /* \| */ -#define ONIG_SYN_OP_LPAREN_SUBEXP (1U<<12) /* (...) */ -#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP (1U<<13) /* \(...\) */ -#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR (1U<<14) /* \A, \Z, \z */ -#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR (1U<<15) /* \G */ -#define ONIG_SYN_OP_DECIMAL_BACKREF (1U<<16) /* \num */ -#define ONIG_SYN_OP_BRACKET_CC (1U<<17) /* [...] */ -#define ONIG_SYN_OP_ESC_W_WORD (1U<<18) /* \w, \W */ -#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END (1U<<19) /* \<. \> */ -#define ONIG_SYN_OP_ESC_B_WORD_BOUND (1U<<20) /* \b, \B */ -#define ONIG_SYN_OP_ESC_S_WHITE_SPACE (1U<<21) /* \s, \S */ -#define ONIG_SYN_OP_ESC_D_DIGIT (1U<<22) /* \d, \D */ -#define ONIG_SYN_OP_LINE_ANCHOR (1U<<23) /* ^, $ */ -#define ONIG_SYN_OP_POSIX_BRACKET (1U<<24) /* [:xxxx:] */ -#define ONIG_SYN_OP_QMARK_NON_GREEDY (1U<<25) /* ??,*?,+?,{n,m}? */ -#define ONIG_SYN_OP_ESC_CONTROL_CHARS (1U<<26) /* \n,\r,\t,\a ... */ -#define ONIG_SYN_OP_ESC_C_CONTROL (1U<<27) /* \cx */ -#define ONIG_SYN_OP_ESC_OCTAL3 (1U<<28) /* \OOO */ -#define ONIG_SYN_OP_ESC_X_HEX2 (1U<<29) /* \xHH */ -#define ONIG_SYN_OP_ESC_X_BRACE_HEX8 (1U<<30) /* \x{7HHHHHHH} */ - -#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE (1U<<0) /* \Q...\E */ -#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT (1U<<1) /* (?...) */ -#define ONIG_SYN_OP2_OPTION_PERL (1U<<2) /* (?imsx),(?-imsx) */ -#define ONIG_SYN_OP2_OPTION_RUBY (1U<<3) /* (?imx), (?-imx) */ -#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT (1U<<4) /* ?+,*+,++ */ -#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL (1U<<5) /* {n,m}+ */ -#define ONIG_SYN_OP2_CCLASS_SET_OP (1U<<6) /* [...&&..[..]..] */ -#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP (1U<<7) /* (?...) */ -#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF (1U<<8) /* \k */ -#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL (1U<<9) /* \g, \g */ -#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY (1U<<10) /* (?@..),(?@..) */ -#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL (1U<<11) /* \C-x */ -#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META (1U<<12) /* \M-x */ -#define ONIG_SYN_OP2_ESC_V_VTAB (1U<<13) /* \v as VTAB */ -#define ONIG_SYN_OP2_ESC_U_HEX4 (1U<<14) /* \uHHHH */ -#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15) /* \`, \' */ -#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16) /* \p{...}, \P{...} */ -#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */ -/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */ -#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19) /* \h, \H */ -#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20) /* \ */ - -/* syntax (behavior) */ -#define ONIG_SYN_CONTEXT_INDEP_ANCHORS (1U<<31) /* not implemented */ -#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS (1U<<0) /* ?, *, +, {n,m} */ -#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS (1U<<1) /* error or ignore */ -#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP (1U<<2) /* ...)... */ -#define ONIG_SYN_ALLOW_INVALID_INTERVAL (1U<<3) /* {??? */ -#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV (1U<<4) /* {,n} => {0,n} */ -#define ONIG_SYN_STRICT_CHECK_BACKREF (1U<<5) /* /(\1)/,/\1()/ ..*/ -#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND (1U<<6) /* (?<=a|bc) */ -#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP (1U<<7) /* see doc/RE */ -#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8) /* (?)(?) */ -#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY (1U<<9) /* a{n}?=(?:a{n})? */ - -/* syntax (behavior) in char class [...] */ -#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC (1U<<20) /* [^...] */ -#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC (1U<<21) /* [..\w..] etc.. */ -#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC (1U<<22) -#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC (1U<<23) /* [0-9-a]=[0-9\-a] */ -/* syntax (behavior) warning */ -#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED (1U<<24) /* [,-,] */ -#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT (1U<<25) /* (?:a*)+ */ - -/* meta character specifiers (onig_set_meta_char()) */ -#define ONIG_META_CHAR_ESCAPE 0 -#define ONIG_META_CHAR_ANYCHAR 1 -#define ONIG_META_CHAR_ANYTIME 2 -#define ONIG_META_CHAR_ZERO_OR_ONE_TIME 3 -#define ONIG_META_CHAR_ONE_OR_MORE_TIME 4 -#define ONIG_META_CHAR_ANYCHAR_ANYTIME 5 - -#define ONIG_INEFFECTIVE_META_CHAR 0 - -/* error codes */ -#define ONIG_IS_PATTERN_ERROR(ecode) ((ecode) <= -100 && (ecode) > -1000) -/* normal return */ -#define ONIG_NORMAL 0 -#define ONIG_MISMATCH -1 -#define ONIG_NO_SUPPORT_CONFIG -2 - -/* internal error */ -#define ONIGERR_MEMORY -5 -#define ONIGERR_TYPE_BUG -6 -#define ONIGERR_PARSER_BUG -11 -#define ONIGERR_STACK_BUG -12 -#define ONIGERR_UNDEFINED_BYTECODE -13 -#define ONIGERR_UNEXPECTED_BYTECODE -14 -#define ONIGERR_MATCH_STACK_LIMIT_OVER -15 -#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED -21 -#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22 -/* general error */ -#define ONIGERR_INVALID_ARGUMENT -30 -/* syntax error */ -#define ONIGERR_END_PATTERN_AT_LEFT_BRACE -100 -#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET -101 -#define ONIGERR_EMPTY_CHAR_CLASS -102 -#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS -103 -#define ONIGERR_END_PATTERN_AT_ESCAPE -104 -#define ONIGERR_END_PATTERN_AT_META -105 -#define ONIGERR_END_PATTERN_AT_CONTROL -106 -#define ONIGERR_META_CODE_SYNTAX -108 -#define ONIGERR_CONTROL_CODE_SYNTAX -109 -#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE -110 -#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE -111 -#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS -112 -#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED -113 -#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID -114 -#define ONIGERR_NESTED_REPEAT_OPERATOR -115 -#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS -116 -#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS -117 -#define ONIGERR_END_PATTERN_IN_GROUP -118 -#define ONIGERR_UNDEFINED_GROUP_OPTION -119 -#define ONIGERR_INVALID_POSIX_BRACKET_TYPE -121 -#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN -122 -#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN -123 -/* values error (syntax error) */ -#define ONIGERR_TOO_BIG_NUMBER -200 -#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE -201 -#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE -202 -#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS -203 -#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE -204 -#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES -205 -#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING -206 -#define ONIGERR_TOO_BIG_BACKREF_NUMBER -207 -#define ONIGERR_INVALID_BACKREF -208 -#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED -209 -#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE -212 -#define ONIGERR_EMPTY_GROUP_NAME -214 -#define ONIGERR_INVALID_GROUP_NAME -215 -#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME -216 -#define ONIGERR_UNDEFINED_NAME_REFERENCE -217 -#define ONIGERR_UNDEFINED_GROUP_REFERENCE -218 -#define ONIGERR_MULTIPLEX_DEFINED_NAME -219 -#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL -220 -#define ONIGERR_NEVER_ENDING_RECURSION -221 -#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222 -#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223 -#define ONIGERR_INVALID_CODE_POINT_VALUE -400 -#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400 -#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401 -#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402 -#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS -403 - -/* errors related to thread */ -#define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT -1001 - - -/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */ -#define ONIG_MAX_CAPTURE_HISTORY_GROUP 31 -#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \ - ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i]) - -typedef struct OnigCaptureTreeNodeStruct { - int group; /* group number */ - int beg; - int end; - int allocated; - int num_childs; - struct OnigCaptureTreeNodeStruct** childs; -} OnigCaptureTreeNode; - -/* match result region type */ -struct re_registers { - int allocated; - int num_regs; - int* beg; - int* end; - /* extended */ - OnigCaptureTreeNode* history_root; /* capture history tree root */ -}; - -/* capture tree traverse */ -#define ONIG_TRAVERSE_CALLBACK_AT_FIRST 1 -#define ONIG_TRAVERSE_CALLBACK_AT_LAST 2 -#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \ - ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST ) - - -#define ONIG_REGION_NOTPOS -1 - -typedef struct re_registers OnigRegion; - -typedef struct { - OnigEncoding enc; - OnigUChar* par; - OnigUChar* par_end; -} OnigErrorInfo; - -typedef struct { - int lower; - int upper; -} OnigRepeatRange; - -typedef void (*OnigWarnFunc) P_((const char* s)); -extern void onig_null_warn P_((const char* s)); -#define ONIG_NULL_WARN onig_null_warn - -#define ONIG_CHAR_TABLE_SIZE 256 - -/* regex_t state */ -#define ONIG_STATE_NORMAL 0 -#define ONIG_STATE_SEARCHING 1 -#define ONIG_STATE_COMPILING -1 -#define ONIG_STATE_MODIFY -2 - -#define ONIG_STATE(reg) \ - ((reg)->state > 0 ? ONIG_STATE_SEARCHING : (reg)->state) - -typedef struct re_pattern_buffer { - /* common members of BBuf(bytes-buffer) */ - unsigned char* p; /* compiled pattern */ - unsigned int used; /* used space for p */ - unsigned int alloc; /* allocated space for p */ - - int state; /* normal, searching, compiling */ - int num_mem; /* used memory(...) num counted from 1 */ - int num_repeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */ - int num_null_check; /* OP_NULL_CHECK_START/END id counter */ - int num_comb_exp_check; /* combination explosion check */ - int num_call; /* number of subexp call */ - unsigned int capture_history; /* (?@...) flag (1-31) */ - unsigned int bt_mem_start; /* need backtrack flag */ - unsigned int bt_mem_end; /* need backtrack flag */ - int stack_pop_level; - int repeat_range_alloc; - OnigRepeatRange* repeat_range; - - OnigEncoding enc; - OnigOptionType options; - OnigSyntaxType* syntax; - OnigCaseFoldType case_fold_flag; - void* name_table; - - /* optimization info (string search, char-map and anchors) */ - int optimize; /* optimize flag */ - int threshold_len; /* search str-length for apply optimize */ - int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */ - OnigDistance anchor_dmin; /* (SEMI_)END_BUF anchor distance */ - OnigDistance anchor_dmax; /* (SEMI_)END_BUF anchor distance */ - int sub_anchor; /* start-anchor for exact or map */ - unsigned char *exact; - unsigned char *exact_end; - unsigned char map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */ - int *int_map; /* BM skip for exact_len > 255 */ - int *int_map_backward; /* BM skip for backward search */ - OnigDistance dmin; /* min-distance of exact or map */ - OnigDistance dmax; /* max-distance of exact or map */ - - /* regex_t link chain */ - struct re_pattern_buffer* chain; /* escape compile-conflict */ -} OnigRegexType; - -typedef OnigRegexType* OnigRegex; - -#ifndef ONIG_ESCAPE_REGEX_T_COLLISION - typedef OnigRegexType regex_t; -#endif - - -typedef struct { - int num_of_elements; - OnigEncoding pattern_enc; - OnigEncoding target_enc; - OnigSyntaxType* syntax; - OnigOptionType option; - OnigCaseFoldType case_fold_flag; -} OnigCompileInfo; - -/* Oniguruma Native API */ -ONIG_EXTERN -int onig_init P_((void)); -ONIG_EXTERN -int onig_error_code_to_str PV_((OnigUChar* s, int err_code, ...)); -ONIG_EXTERN -void onig_set_warn_func P_((OnigWarnFunc f)); -ONIG_EXTERN -void onig_set_verb_warn_func P_((OnigWarnFunc f)); -ONIG_EXTERN -int onig_new P_((OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_reg_init P_((regex_t* reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, OnigSyntaxType* syntax)); -int onig_new_without_alloc P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_new_deluxe P_((OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo)); -ONIG_EXTERN -void onig_free P_((OnigRegex)); -ONIG_EXTERN -void onig_free_body P_((OnigRegex)); -ONIG_EXTERN -int onig_recompile P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_recompile_deluxe P_((OnigRegex reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_search P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option)); -ONIG_EXTERN -int onig_match P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option)); -ONIG_EXTERN -OnigRegion* onig_region_new P_((void)); -ONIG_EXTERN -void onig_region_init P_((OnigRegion* region)); -ONIG_EXTERN -void onig_region_free P_((OnigRegion* region, int free_self)); -ONIG_EXTERN -void onig_region_copy P_((OnigRegion* to, OnigRegion* from)); -ONIG_EXTERN -void onig_region_clear P_((OnigRegion* region)); -ONIG_EXTERN -int onig_region_resize P_((OnigRegion* region, int n)); -ONIG_EXTERN -int onig_region_set P_((OnigRegion* region, int at, int beg, int end)); -ONIG_EXTERN -int onig_name_to_group_numbers P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums)); -ONIG_EXTERN -int onig_name_to_backref_number P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, OnigRegion *region)); -ONIG_EXTERN -int onig_foreach_name P_((OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg)); -ONIG_EXTERN -int onig_number_of_names P_((OnigRegex reg)); -ONIG_EXTERN -int onig_number_of_captures P_((OnigRegex reg)); -ONIG_EXTERN -int onig_number_of_capture_histories P_((OnigRegex reg)); -ONIG_EXTERN -OnigCaptureTreeNode* onig_get_capture_tree P_((OnigRegion* region)); -ONIG_EXTERN -int onig_capture_tree_traverse P_((OnigRegion* region, int at, int(*callback_func)(int,int,int,int,int,void*), void* arg)); -ONIG_EXTERN -int onig_noname_group_capture_is_active P_((OnigRegex reg)); -ONIG_EXTERN -OnigEncoding onig_get_encoding P_((OnigRegex reg)); -ONIG_EXTERN -OnigOptionType onig_get_options P_((OnigRegex reg)); -ONIG_EXTERN -OnigCaseFoldType onig_get_case_fold_flag P_((OnigRegex reg)); -ONIG_EXTERN -OnigSyntaxType* onig_get_syntax P_((OnigRegex reg)); -ONIG_EXTERN -int onig_set_default_syntax P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -void onig_copy_syntax P_((OnigSyntaxType* to, OnigSyntaxType* from)); -ONIG_EXTERN -unsigned int onig_get_syntax_op P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -unsigned int onig_get_syntax_op2 P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -unsigned int onig_get_syntax_behavior P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -OnigOptionType onig_get_syntax_options P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -void onig_set_syntax_op P_((OnigSyntaxType* syntax, unsigned int op)); -ONIG_EXTERN -void onig_set_syntax_op2 P_((OnigSyntaxType* syntax, unsigned int op2)); -ONIG_EXTERN -void onig_set_syntax_behavior P_((OnigSyntaxType* syntax, unsigned int behavior)); -ONIG_EXTERN -void onig_set_syntax_options P_((OnigSyntaxType* syntax, OnigOptionType options)); -ONIG_EXTERN -int onig_set_meta_char P_((OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code)); -ONIG_EXTERN -void onig_copy_encoding P_((OnigEncoding to, OnigEncoding from)); -ONIG_EXTERN -OnigCaseFoldType onig_get_default_case_fold_flag P_((void)); -ONIG_EXTERN -int onig_set_default_case_fold_flag P_((OnigCaseFoldType case_fold_flag)); -ONIG_EXTERN -unsigned int onig_get_match_stack_limit_size P_((void)); -ONIG_EXTERN -int onig_set_match_stack_limit_size P_((unsigned int size)); -ONIG_EXTERN -int onig_end P_((void)); -ONIG_EXTERN -const char* onig_version P_((void)); -ONIG_EXTERN -const char* onig_copyright P_((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ONIGURUMA_H */ diff --git a/native/frameworks/CocoaOniguruma.framework/Resources/English.lproj/InfoPlist.strings b/native/frameworks/CocoaOniguruma.framework/Resources/English.lproj/InfoPlist.strings deleted file mode 100644 index 39d5b82c7..000000000 Binary files a/native/frameworks/CocoaOniguruma.framework/Resources/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/native/frameworks/CocoaOniguruma.framework/Resources/Info.plist b/native/frameworks/CocoaOniguruma.framework/Resources/Info.plist deleted file mode 100644 index ccdedf455..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Resources/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - BuildMachineOSBuild - 11E2620 - CFBundleDevelopmentRegion - English - CFBundleExecutable - CocoaOniguruma - CFBundleIdentifier - net.limechat.CocoaOniguruma - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - CocoaOniguruma - CFBundlePackageType - FMWK - CFBundleSignature - ???? - CFBundleVersion - 1.0 - DTCompiler - - DTPlatformBuild - 4E3002 - DTPlatformVersion - GM - DTSDKBuild - 11E2620 - DTSDKName - - DTXcode - 0433 - DTXcodeBuild - 4E3002 - - diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/A/CocoaOniguruma b/native/frameworks/CocoaOniguruma.framework/Versions/A/CocoaOniguruma deleted file mode 100755 index 3799f6f6b..000000000 Binary files a/native/frameworks/CocoaOniguruma.framework/Versions/A/CocoaOniguruma and /dev/null differ diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/OnigRegexp.h b/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/OnigRegexp.h deleted file mode 100644 index 84f24b46d..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/OnigRegexp.h +++ /dev/null @@ -1,91 +0,0 @@ -// CocoaOniguruma is copyrighted free software by Satoshi Nakagawa . -// You can redistribute it and/or modify it under the new BSD license. - -#import -#import "oniguruma.h" -#import "OnigRegexpUtility.h" - - -@class OnigResult; - -typedef enum { - OnigOptionNone = ONIG_OPTION_NONE, - OnigOptionIgnorecase = ONIG_OPTION_IGNORECASE, - OnigOptionExtend = ONIG_OPTION_EXTEND, - OnigOptionMultiline = ONIG_OPTION_MULTILINE, - OnigOptionSingleline = ONIG_OPTION_SINGLELINE, - OnigOptionFindLongest = ONIG_OPTION_FIND_LONGEST, - OnigOptionFindNotEmpty = ONIG_OPTION_FIND_NOT_EMPTY, - OnigOptionNegateSingleLine = ONIG_OPTION_NEGATE_SINGLELINE, - OnigOptionDontCaptureGroup = ONIG_OPTION_DONT_CAPTURE_GROUP, - OnigOptionCaptureGroup = ONIG_OPTION_CAPTURE_GROUP, - - /* options (search time) */ - OnigOptionNotbol = ONIG_OPTION_NOTBOL, - OnigOptionNoteol = ONIG_OPTION_NOTEOL, - OnigOptionPosixRegion = ONIG_OPTION_POSIX_REGION, - OnigOptionMaxbit = ONIG_OPTION_MAXBIT -} OnigOption; - -@interface OnigRegexp : NSObject -{ - regex_t* _entity; - NSString* _expression; -} - -+ (OnigRegexp*)compile:(NSString*)expression; -+ (OnigRegexp*)compile:(NSString*)expression error:(NSError **)error; -+ (OnigRegexp*)compileIgnorecase:(NSString*)expression; -+ (OnigRegexp*)compileIgnorecase:(NSString*)expression error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline extended:(BOOL)extended; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline extended:(BOOL)extended error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression options:(OnigOption)options; -+ (OnigRegexp*)compile:(NSString*)expression options:(OnigOption)options error:(NSError **)error; - -- (OnigResult*)search:(NSString*)target; -- (OnigResult*)search:(NSString*)target start:(int)start; -- (OnigResult*)search:(NSString*)target start:(int)start end:(int)end; -- (OnigResult*)search:(NSString*)target range:(NSRange)range; - -- (OnigResult*)match:(NSString*)target; -- (OnigResult*)match:(NSString*)target start:(int)start; - -- (NSUInteger)captureCount; -- (NSString*)expression; - -@end - - -@interface OnigResult : NSObject -{ - OnigRegexp* _expression; - OnigRegion* _region; - NSString* _target; - NSMutableArray* _captureNames; -} - -- (NSString*)target; - -- (int)count; -- (NSString*)stringAt:(int)index; -- (NSArray*)strings; -- (NSRange)rangeAt:(int)index; -- (int)locationAt:(int)index; -- (int)lengthAt:(int)index; - -- (NSString*)body; -- (NSRange)bodyRange; - -- (NSString*)preMatch; -- (NSString*)postMatch; - -// named capture support -- (NSArray*)captureNames; -- (int)indexForName:(NSString*)name; -- (NSIndexSet*)indexesForName:(NSString*)name; -- (NSString*)stringForName:(NSString*)name; -- (NSArray*)stringsForName:(NSString*)name; - -@end diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/OnigRegexpUtility.h b/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/OnigRegexpUtility.h deleted file mode 100644 index 245ebae3d..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/OnigRegexpUtility.h +++ /dev/null @@ -1,57 +0,0 @@ -// CocoaOniguruma is copyrighted free software by Satoshi Nakagawa . -// You can redistribute it and/or modify it under the new BSD license. - -#import -#import "oniguruma.h" -#import "OnigRegexp.h" - - -@class OnigRegexp; -@class OnigResult; - - -@interface NSString (OnigRegexpUtility) - -// pattern is OnigRegexp or NSString - -- (NSRange)rangeOfRegexp:(id)pattern; - -// based on ruby's split - -- (NSArray*)split; -- (NSArray*)splitByRegexp:(id)pattern; -- (NSArray*)splitByRegexp:(id)pattern limit:(int)limit; - -// based on ruby's gsub - -- (NSString*)replaceByRegexp:(id)pattern with:(NSString*)string; -- (NSString*)replaceAllByRegexp:(id)pattern with:(NSString*)string; - -- (NSString*)replaceByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; -- (NSString*)replaceAllByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; - -#if defined(NS_BLOCKS_AVAILABLE) -- (NSString*)replaceByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -- (NSString*)replaceAllByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -#endif - -@end - - -@interface NSMutableString (OnigRegexpUtility) - -// pattern is OnigRegexp or NSString - -// based on ruby's gsub - -- (NSMutableString*)replaceByRegexp:(id)pattern with:(NSString*)string; -- (NSMutableString*)replaceAllByRegexp:(id)pattern with:(NSString*)string; - -- (NSMutableString*)replaceByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; -- (NSMutableString*)replaceAllByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; - -#if defined(NS_BLOCKS_AVAILABLE) -- (NSMutableString*)replaceByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -- (NSMutableString*)replaceAllByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -#endif -@end diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/oniguruma.h b/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/oniguruma.h deleted file mode 100644 index 8c6322c9b..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/A/Headers/oniguruma.h +++ /dev/null @@ -1,770 +0,0 @@ -#ifndef ONIGURUMA_H -#define ONIGURUMA_H -/********************************************************************** - oniguruma.h - Oniguruma (regular expression library) -**********************************************************************/ -/*- - * Copyright (c) 2002-2009 K.Kosako - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define ONIGURUMA -#define ONIGURUMA_VERSION_MAJOR 5 -#define ONIGURUMA_VERSION_MINOR 9 -#define ONIGURUMA_VERSION_TEENY 2 - -#ifdef __cplusplus -# ifndef HAVE_PROTOTYPES -# define HAVE_PROTOTYPES 1 -# endif -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -/* escape Mac OS X/Xcode 2.4/gcc 4.0.1 problem */ -#if defined(__APPLE__) && defined(__GNUC__) && __GNUC__ >= 4 -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -#ifdef HAVE_STDARG_H -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -#ifndef P_ -#if defined(__STDC__) || defined(_WIN32) -# define P_(args) args -#else -# define P_(args) () -#endif -#endif - -#ifndef PV_ -#ifdef HAVE_STDARG_PROTOTYPES -# define PV_(args) args -#else -# define PV_(args) () -#endif -#endif - -#ifndef ONIG_EXTERN -#if defined(_WIN32) && !defined(__GNUC__) -#if defined(EXPORT) || defined(RUBY_EXPORT) -#define ONIG_EXTERN extern __declspec(dllexport) -#else -#define ONIG_EXTERN extern __declspec(dllimport) -#endif -#endif -#endif - -#ifndef ONIG_EXTERN -#define ONIG_EXTERN extern -#endif - -/* PART: character encoding */ - -#ifndef ONIG_ESCAPE_UCHAR_COLLISION -#define UChar OnigUChar -#endif - -typedef unsigned char OnigUChar; -typedef unsigned long OnigCodePoint; -typedef unsigned int OnigCtype; -typedef unsigned int OnigDistance; - -#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0) - -typedef unsigned int OnigCaseFoldType; /* case fold flag */ - -ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag; - -/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA (1<<1) */ -/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH (1<<2) */ -#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20) -#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30) - -#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR -#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag - - -#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3 -#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13 -/* 13 => Unicode:0x1ffc */ - -/* code range */ -#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0]) -#define ONIGENC_CODE_RANGE_FROM(range,i) range[((i)*2) + 1] -#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2] - -typedef struct { - int byte_len; /* argument(original) character(s) byte length */ - int code_len; /* number of code */ - OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN]; -} OnigCaseFoldCodeItem; - -typedef struct { - OnigCodePoint esc; - OnigCodePoint anychar; - OnigCodePoint anytime; - OnigCodePoint zero_or_one_time; - OnigCodePoint one_or_more_time; - OnigCodePoint anychar_anytime; -} OnigMetaCharTableType; - -typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg); - -typedef struct OnigEncodingTypeST { - int (*mbc_enc_len)(const OnigUChar* p); - const char* name; - int max_enc_len; - int min_enc_len; - int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end); - OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end); - int (*code_to_mbclen)(OnigCodePoint code); - int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf); - int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to); - int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg); - int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[]); - int (*property_name_to_ctype)(struct OnigEncodingTypeST* enc, OnigUChar* p, OnigUChar* end); - int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype); - int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[]); - OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p); - int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end); -} OnigEncodingType; - -typedef OnigEncodingType* OnigEncoding; - -ONIG_EXTERN OnigEncodingType OnigEncodingASCII; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_BE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_LE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_BE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_LE; - -#define ONIG_ENCODING_ASCII (&OnigEncodingASCII) -#define ONIG_ENCODING_UTF16_BE (&OnigEncodingUTF16_BE) -#define ONIG_ENCODING_UTF16_LE (&OnigEncodingUTF16_LE) -#define ONIG_ENCODING_UTF32_BE (&OnigEncodingUTF32_BE) -#define ONIG_ENCODING_UTF32_LE (&OnigEncodingUTF32_LE) - -#define ONIG_ENCODING_UNDEF ((OnigEncoding )0) - - -/* work size */ -#define ONIGENC_CODE_TO_MBC_MAXLEN 7 -#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18 -/* 18: 6(max-byte) * 3(case-fold chars) */ - -/* character types */ -#define ONIGENC_CTYPE_NEWLINE 0 -#define ONIGENC_CTYPE_ALPHA 1 -#define ONIGENC_CTYPE_BLANK 2 -#define ONIGENC_CTYPE_CNTRL 3 -#define ONIGENC_CTYPE_DIGIT 4 -#define ONIGENC_CTYPE_GRAPH 5 -#define ONIGENC_CTYPE_LOWER 6 -#define ONIGENC_CTYPE_PRINT 7 -#define ONIGENC_CTYPE_PUNCT 8 -#define ONIGENC_CTYPE_SPACE 9 -#define ONIGENC_CTYPE_UPPER 10 -#define ONIGENC_CTYPE_XDIGIT 11 -#define ONIGENC_CTYPE_WORD 12 -#define ONIGENC_CTYPE_ALNUM 13 /* alpha || digit */ -#define ONIGENC_CTYPE_ASCII 14 -#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII - - -#define onig_enc_len(enc,p,end) ONIGENC_MBC_ENC_LEN(enc,p) - -#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF) -#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1) -#define ONIGENC_IS_MBC_HEAD(enc,p) (ONIGENC_MBC_ENC_LEN(enc,p) != 1) -#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128) -#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128) -#define ONIGENC_IS_MBC_WORD(enc,s,end) \ - ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end)) - - -#define ONIGENC_NAME(enc) ((enc)->name) - -#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \ - (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf) -#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \ - (enc)->is_allowed_reverse_match(s,end) -#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \ - (enc)->left_adjust_char_head(start, s) -#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \ - (enc)->apply_all_case_fold(case_fold_flag,f,arg) -#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \ - (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs) -#define ONIGENC_STEP_BACK(enc,start,s,n) \ - onigenc_step_back((enc),(start),(s),(n)) - -#define ONIGENC_MBC_ENC_LEN(enc,p) (enc)->mbc_enc_len(p) -#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len) -#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc) -#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len) -#define ONIGENC_IS_MBC_NEWLINE(enc,p,end) (enc)->is_mbc_newline((p),(end)) -#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end)) -#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code) -#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf) -#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \ - (enc)->property_name_to_ctype(enc,p,end) - -#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype) - -#define ONIGENC_IS_CODE_NEWLINE(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE) -#define ONIGENC_IS_CODE_GRAPH(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH) -#define ONIGENC_IS_CODE_PRINT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT) -#define ONIGENC_IS_CODE_ALNUM(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM) -#define ONIGENC_IS_CODE_ALPHA(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA) -#define ONIGENC_IS_CODE_LOWER(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER) -#define ONIGENC_IS_CODE_UPPER(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER) -#define ONIGENC_IS_CODE_CNTRL(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL) -#define ONIGENC_IS_CODE_PUNCT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT) -#define ONIGENC_IS_CODE_SPACE(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE) -#define ONIGENC_IS_CODE_BLANK(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK) -#define ONIGENC_IS_CODE_DIGIT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT) -#define ONIGENC_IS_CODE_XDIGIT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT) -#define ONIGENC_IS_CODE_WORD(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD) - -#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \ - (enc)->get_ctype_code_range(ctype,sbout,ranges) - -ONIG_EXTERN -OnigUChar* onigenc_step_back P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, int n)); - - -/* encoding API */ -ONIG_EXTERN -int onigenc_init P_((void)); -ONIG_EXTERN -int onigenc_set_default_encoding P_((OnigEncoding enc)); -ONIG_EXTERN -OnigEncoding onigenc_get_default_encoding P_((void)); -ONIG_EXTERN -void onigenc_set_default_caseconv_table P_((const OnigUChar* table)); -ONIG_EXTERN -OnigUChar* onigenc_get_right_adjust_char_head_with_prev P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar** prev)); -ONIG_EXTERN -OnigUChar* onigenc_get_prev_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -OnigUChar* onigenc_get_left_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -OnigUChar* onigenc_get_right_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -int onigenc_strlen P_((OnigEncoding enc, const OnigUChar* p, const OnigUChar* end)); -ONIG_EXTERN -int onigenc_strlen_null P_((OnigEncoding enc, const OnigUChar* p)); -ONIG_EXTERN -int onigenc_str_bytelen_null P_((OnigEncoding enc, const OnigUChar* p)); - - - -/* PART: regular expression */ - -/* config parameters */ -#define ONIG_NREGION 10 -#define ONIG_MAX_BACKREF_NUM 1000 -#define ONIG_MAX_REPEAT_NUM 100000 -#define ONIG_MAX_MULTI_BYTE_RANGES_NUM 10000 -/* constants */ -#define ONIG_MAX_ERROR_MESSAGE_LEN 90 - -typedef unsigned int OnigOptionType; - -#define ONIG_OPTION_DEFAULT ONIG_OPTION_NONE - -/* options */ -#define ONIG_OPTION_NONE 0U -#define ONIG_OPTION_IGNORECASE 1U -#define ONIG_OPTION_EXTEND (ONIG_OPTION_IGNORECASE << 1) -#define ONIG_OPTION_MULTILINE (ONIG_OPTION_EXTEND << 1) -#define ONIG_OPTION_SINGLELINE (ONIG_OPTION_MULTILINE << 1) -#define ONIG_OPTION_FIND_LONGEST (ONIG_OPTION_SINGLELINE << 1) -#define ONIG_OPTION_FIND_NOT_EMPTY (ONIG_OPTION_FIND_LONGEST << 1) -#define ONIG_OPTION_NEGATE_SINGLELINE (ONIG_OPTION_FIND_NOT_EMPTY << 1) -#define ONIG_OPTION_DONT_CAPTURE_GROUP (ONIG_OPTION_NEGATE_SINGLELINE << 1) -#define ONIG_OPTION_CAPTURE_GROUP (ONIG_OPTION_DONT_CAPTURE_GROUP << 1) -/* options (search time) */ -#define ONIG_OPTION_NOTBOL (ONIG_OPTION_CAPTURE_GROUP << 1) -#define ONIG_OPTION_NOTEOL (ONIG_OPTION_NOTBOL << 1) -#define ONIG_OPTION_POSIX_REGION (ONIG_OPTION_NOTEOL << 1) -#define ONIG_OPTION_MAXBIT ONIG_OPTION_POSIX_REGION /* limit */ - -#define ONIG_OPTION_ON(options,regopt) ((options) |= (regopt)) -#define ONIG_OPTION_OFF(options,regopt) ((options) &= ~(regopt)) -#define ONIG_IS_OPTION_ON(options,option) ((options) & (option)) - -/* syntax */ -typedef struct { - unsigned int op; - unsigned int op2; - unsigned int behavior; - OnigOptionType options; /* default option */ - OnigMetaCharTableType meta_char_table; -} OnigSyntaxType; - -ONIG_EXTERN OnigSyntaxType OnigSyntaxASIS; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixBasic; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixExtended; -ONIG_EXTERN OnigSyntaxType OnigSyntaxEmacs; -ONIG_EXTERN OnigSyntaxType OnigSyntaxGrep; -ONIG_EXTERN OnigSyntaxType OnigSyntaxGnuRegex; -ONIG_EXTERN OnigSyntaxType OnigSyntaxJava; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl_NG; -ONIG_EXTERN OnigSyntaxType OnigSyntaxRuby; - -/* predefined syntaxes (see regsyntax.c) */ -#define ONIG_SYNTAX_ASIS (&OnigSyntaxASIS) -#define ONIG_SYNTAX_POSIX_BASIC (&OnigSyntaxPosixBasic) -#define ONIG_SYNTAX_POSIX_EXTENDED (&OnigSyntaxPosixExtended) -#define ONIG_SYNTAX_EMACS (&OnigSyntaxEmacs) -#define ONIG_SYNTAX_GREP (&OnigSyntaxGrep) -#define ONIG_SYNTAX_GNU_REGEX (&OnigSyntaxGnuRegex) -#define ONIG_SYNTAX_JAVA (&OnigSyntaxJava) -#define ONIG_SYNTAX_PERL (&OnigSyntaxPerl) -#define ONIG_SYNTAX_PERL_NG (&OnigSyntaxPerl_NG) -#define ONIG_SYNTAX_RUBY (&OnigSyntaxRuby) - -/* default syntax */ -ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax; -#define ONIG_SYNTAX_DEFAULT OnigDefaultSyntax - -/* syntax (operators) */ -#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS (1U<<0) -#define ONIG_SYN_OP_DOT_ANYCHAR (1U<<1) /* . */ -#define ONIG_SYN_OP_ASTERISK_ZERO_INF (1U<<2) /* * */ -#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF (1U<<3) -#define ONIG_SYN_OP_PLUS_ONE_INF (1U<<4) /* + */ -#define ONIG_SYN_OP_ESC_PLUS_ONE_INF (1U<<5) -#define ONIG_SYN_OP_QMARK_ZERO_ONE (1U<<6) /* ? */ -#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE (1U<<7) -#define ONIG_SYN_OP_BRACE_INTERVAL (1U<<8) /* {lower,upper} */ -#define ONIG_SYN_OP_ESC_BRACE_INTERVAL (1U<<9) /* \{lower,upper\} */ -#define ONIG_SYN_OP_VBAR_ALT (1U<<10) /* | */ -#define ONIG_SYN_OP_ESC_VBAR_ALT (1U<<11) /* \| */ -#define ONIG_SYN_OP_LPAREN_SUBEXP (1U<<12) /* (...) */ -#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP (1U<<13) /* \(...\) */ -#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR (1U<<14) /* \A, \Z, \z */ -#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR (1U<<15) /* \G */ -#define ONIG_SYN_OP_DECIMAL_BACKREF (1U<<16) /* \num */ -#define ONIG_SYN_OP_BRACKET_CC (1U<<17) /* [...] */ -#define ONIG_SYN_OP_ESC_W_WORD (1U<<18) /* \w, \W */ -#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END (1U<<19) /* \<. \> */ -#define ONIG_SYN_OP_ESC_B_WORD_BOUND (1U<<20) /* \b, \B */ -#define ONIG_SYN_OP_ESC_S_WHITE_SPACE (1U<<21) /* \s, \S */ -#define ONIG_SYN_OP_ESC_D_DIGIT (1U<<22) /* \d, \D */ -#define ONIG_SYN_OP_LINE_ANCHOR (1U<<23) /* ^, $ */ -#define ONIG_SYN_OP_POSIX_BRACKET (1U<<24) /* [:xxxx:] */ -#define ONIG_SYN_OP_QMARK_NON_GREEDY (1U<<25) /* ??,*?,+?,{n,m}? */ -#define ONIG_SYN_OP_ESC_CONTROL_CHARS (1U<<26) /* \n,\r,\t,\a ... */ -#define ONIG_SYN_OP_ESC_C_CONTROL (1U<<27) /* \cx */ -#define ONIG_SYN_OP_ESC_OCTAL3 (1U<<28) /* \OOO */ -#define ONIG_SYN_OP_ESC_X_HEX2 (1U<<29) /* \xHH */ -#define ONIG_SYN_OP_ESC_X_BRACE_HEX8 (1U<<30) /* \x{7HHHHHHH} */ - -#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE (1U<<0) /* \Q...\E */ -#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT (1U<<1) /* (?...) */ -#define ONIG_SYN_OP2_OPTION_PERL (1U<<2) /* (?imsx),(?-imsx) */ -#define ONIG_SYN_OP2_OPTION_RUBY (1U<<3) /* (?imx), (?-imx) */ -#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT (1U<<4) /* ?+,*+,++ */ -#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL (1U<<5) /* {n,m}+ */ -#define ONIG_SYN_OP2_CCLASS_SET_OP (1U<<6) /* [...&&..[..]..] */ -#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP (1U<<7) /* (?...) */ -#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF (1U<<8) /* \k */ -#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL (1U<<9) /* \g, \g */ -#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY (1U<<10) /* (?@..),(?@..) */ -#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL (1U<<11) /* \C-x */ -#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META (1U<<12) /* \M-x */ -#define ONIG_SYN_OP2_ESC_V_VTAB (1U<<13) /* \v as VTAB */ -#define ONIG_SYN_OP2_ESC_U_HEX4 (1U<<14) /* \uHHHH */ -#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15) /* \`, \' */ -#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16) /* \p{...}, \P{...} */ -#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */ -/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */ -#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19) /* \h, \H */ -#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20) /* \ */ - -/* syntax (behavior) */ -#define ONIG_SYN_CONTEXT_INDEP_ANCHORS (1U<<31) /* not implemented */ -#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS (1U<<0) /* ?, *, +, {n,m} */ -#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS (1U<<1) /* error or ignore */ -#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP (1U<<2) /* ...)... */ -#define ONIG_SYN_ALLOW_INVALID_INTERVAL (1U<<3) /* {??? */ -#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV (1U<<4) /* {,n} => {0,n} */ -#define ONIG_SYN_STRICT_CHECK_BACKREF (1U<<5) /* /(\1)/,/\1()/ ..*/ -#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND (1U<<6) /* (?<=a|bc) */ -#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP (1U<<7) /* see doc/RE */ -#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8) /* (?)(?) */ -#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY (1U<<9) /* a{n}?=(?:a{n})? */ - -/* syntax (behavior) in char class [...] */ -#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC (1U<<20) /* [^...] */ -#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC (1U<<21) /* [..\w..] etc.. */ -#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC (1U<<22) -#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC (1U<<23) /* [0-9-a]=[0-9\-a] */ -/* syntax (behavior) warning */ -#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED (1U<<24) /* [,-,] */ -#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT (1U<<25) /* (?:a*)+ */ - -/* meta character specifiers (onig_set_meta_char()) */ -#define ONIG_META_CHAR_ESCAPE 0 -#define ONIG_META_CHAR_ANYCHAR 1 -#define ONIG_META_CHAR_ANYTIME 2 -#define ONIG_META_CHAR_ZERO_OR_ONE_TIME 3 -#define ONIG_META_CHAR_ONE_OR_MORE_TIME 4 -#define ONIG_META_CHAR_ANYCHAR_ANYTIME 5 - -#define ONIG_INEFFECTIVE_META_CHAR 0 - -/* error codes */ -#define ONIG_IS_PATTERN_ERROR(ecode) ((ecode) <= -100 && (ecode) > -1000) -/* normal return */ -#define ONIG_NORMAL 0 -#define ONIG_MISMATCH -1 -#define ONIG_NO_SUPPORT_CONFIG -2 - -/* internal error */ -#define ONIGERR_MEMORY -5 -#define ONIGERR_TYPE_BUG -6 -#define ONIGERR_PARSER_BUG -11 -#define ONIGERR_STACK_BUG -12 -#define ONIGERR_UNDEFINED_BYTECODE -13 -#define ONIGERR_UNEXPECTED_BYTECODE -14 -#define ONIGERR_MATCH_STACK_LIMIT_OVER -15 -#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED -21 -#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22 -/* general error */ -#define ONIGERR_INVALID_ARGUMENT -30 -/* syntax error */ -#define ONIGERR_END_PATTERN_AT_LEFT_BRACE -100 -#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET -101 -#define ONIGERR_EMPTY_CHAR_CLASS -102 -#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS -103 -#define ONIGERR_END_PATTERN_AT_ESCAPE -104 -#define ONIGERR_END_PATTERN_AT_META -105 -#define ONIGERR_END_PATTERN_AT_CONTROL -106 -#define ONIGERR_META_CODE_SYNTAX -108 -#define ONIGERR_CONTROL_CODE_SYNTAX -109 -#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE -110 -#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE -111 -#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS -112 -#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED -113 -#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID -114 -#define ONIGERR_NESTED_REPEAT_OPERATOR -115 -#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS -116 -#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS -117 -#define ONIGERR_END_PATTERN_IN_GROUP -118 -#define ONIGERR_UNDEFINED_GROUP_OPTION -119 -#define ONIGERR_INVALID_POSIX_BRACKET_TYPE -121 -#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN -122 -#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN -123 -/* values error (syntax error) */ -#define ONIGERR_TOO_BIG_NUMBER -200 -#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE -201 -#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE -202 -#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS -203 -#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE -204 -#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES -205 -#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING -206 -#define ONIGERR_TOO_BIG_BACKREF_NUMBER -207 -#define ONIGERR_INVALID_BACKREF -208 -#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED -209 -#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE -212 -#define ONIGERR_EMPTY_GROUP_NAME -214 -#define ONIGERR_INVALID_GROUP_NAME -215 -#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME -216 -#define ONIGERR_UNDEFINED_NAME_REFERENCE -217 -#define ONIGERR_UNDEFINED_GROUP_REFERENCE -218 -#define ONIGERR_MULTIPLEX_DEFINED_NAME -219 -#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL -220 -#define ONIGERR_NEVER_ENDING_RECURSION -221 -#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222 -#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223 -#define ONIGERR_INVALID_CODE_POINT_VALUE -400 -#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400 -#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401 -#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402 -#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS -403 - -/* errors related to thread */ -#define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT -1001 - - -/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */ -#define ONIG_MAX_CAPTURE_HISTORY_GROUP 31 -#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \ - ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i]) - -typedef struct OnigCaptureTreeNodeStruct { - int group; /* group number */ - int beg; - int end; - int allocated; - int num_childs; - struct OnigCaptureTreeNodeStruct** childs; -} OnigCaptureTreeNode; - -/* match result region type */ -struct re_registers { - int allocated; - int num_regs; - int* beg; - int* end; - /* extended */ - OnigCaptureTreeNode* history_root; /* capture history tree root */ -}; - -/* capture tree traverse */ -#define ONIG_TRAVERSE_CALLBACK_AT_FIRST 1 -#define ONIG_TRAVERSE_CALLBACK_AT_LAST 2 -#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \ - ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST ) - - -#define ONIG_REGION_NOTPOS -1 - -typedef struct re_registers OnigRegion; - -typedef struct { - OnigEncoding enc; - OnigUChar* par; - OnigUChar* par_end; -} OnigErrorInfo; - -typedef struct { - int lower; - int upper; -} OnigRepeatRange; - -typedef void (*OnigWarnFunc) P_((const char* s)); -extern void onig_null_warn P_((const char* s)); -#define ONIG_NULL_WARN onig_null_warn - -#define ONIG_CHAR_TABLE_SIZE 256 - -/* regex_t state */ -#define ONIG_STATE_NORMAL 0 -#define ONIG_STATE_SEARCHING 1 -#define ONIG_STATE_COMPILING -1 -#define ONIG_STATE_MODIFY -2 - -#define ONIG_STATE(reg) \ - ((reg)->state > 0 ? ONIG_STATE_SEARCHING : (reg)->state) - -typedef struct re_pattern_buffer { - /* common members of BBuf(bytes-buffer) */ - unsigned char* p; /* compiled pattern */ - unsigned int used; /* used space for p */ - unsigned int alloc; /* allocated space for p */ - - int state; /* normal, searching, compiling */ - int num_mem; /* used memory(...) num counted from 1 */ - int num_repeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */ - int num_null_check; /* OP_NULL_CHECK_START/END id counter */ - int num_comb_exp_check; /* combination explosion check */ - int num_call; /* number of subexp call */ - unsigned int capture_history; /* (?@...) flag (1-31) */ - unsigned int bt_mem_start; /* need backtrack flag */ - unsigned int bt_mem_end; /* need backtrack flag */ - int stack_pop_level; - int repeat_range_alloc; - OnigRepeatRange* repeat_range; - - OnigEncoding enc; - OnigOptionType options; - OnigSyntaxType* syntax; - OnigCaseFoldType case_fold_flag; - void* name_table; - - /* optimization info (string search, char-map and anchors) */ - int optimize; /* optimize flag */ - int threshold_len; /* search str-length for apply optimize */ - int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */ - OnigDistance anchor_dmin; /* (SEMI_)END_BUF anchor distance */ - OnigDistance anchor_dmax; /* (SEMI_)END_BUF anchor distance */ - int sub_anchor; /* start-anchor for exact or map */ - unsigned char *exact; - unsigned char *exact_end; - unsigned char map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */ - int *int_map; /* BM skip for exact_len > 255 */ - int *int_map_backward; /* BM skip for backward search */ - OnigDistance dmin; /* min-distance of exact or map */ - OnigDistance dmax; /* max-distance of exact or map */ - - /* regex_t link chain */ - struct re_pattern_buffer* chain; /* escape compile-conflict */ -} OnigRegexType; - -typedef OnigRegexType* OnigRegex; - -#ifndef ONIG_ESCAPE_REGEX_T_COLLISION - typedef OnigRegexType regex_t; -#endif - - -typedef struct { - int num_of_elements; - OnigEncoding pattern_enc; - OnigEncoding target_enc; - OnigSyntaxType* syntax; - OnigOptionType option; - OnigCaseFoldType case_fold_flag; -} OnigCompileInfo; - -/* Oniguruma Native API */ -ONIG_EXTERN -int onig_init P_((void)); -ONIG_EXTERN -int onig_error_code_to_str PV_((OnigUChar* s, int err_code, ...)); -ONIG_EXTERN -void onig_set_warn_func P_((OnigWarnFunc f)); -ONIG_EXTERN -void onig_set_verb_warn_func P_((OnigWarnFunc f)); -ONIG_EXTERN -int onig_new P_((OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_reg_init P_((regex_t* reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, OnigSyntaxType* syntax)); -int onig_new_without_alloc P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_new_deluxe P_((OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo)); -ONIG_EXTERN -void onig_free P_((OnigRegex)); -ONIG_EXTERN -void onig_free_body P_((OnigRegex)); -ONIG_EXTERN -int onig_recompile P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_recompile_deluxe P_((OnigRegex reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_search P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option)); -ONIG_EXTERN -int onig_match P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option)); -ONIG_EXTERN -OnigRegion* onig_region_new P_((void)); -ONIG_EXTERN -void onig_region_init P_((OnigRegion* region)); -ONIG_EXTERN -void onig_region_free P_((OnigRegion* region, int free_self)); -ONIG_EXTERN -void onig_region_copy P_((OnigRegion* to, OnigRegion* from)); -ONIG_EXTERN -void onig_region_clear P_((OnigRegion* region)); -ONIG_EXTERN -int onig_region_resize P_((OnigRegion* region, int n)); -ONIG_EXTERN -int onig_region_set P_((OnigRegion* region, int at, int beg, int end)); -ONIG_EXTERN -int onig_name_to_group_numbers P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums)); -ONIG_EXTERN -int onig_name_to_backref_number P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, OnigRegion *region)); -ONIG_EXTERN -int onig_foreach_name P_((OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg)); -ONIG_EXTERN -int onig_number_of_names P_((OnigRegex reg)); -ONIG_EXTERN -int onig_number_of_captures P_((OnigRegex reg)); -ONIG_EXTERN -int onig_number_of_capture_histories P_((OnigRegex reg)); -ONIG_EXTERN -OnigCaptureTreeNode* onig_get_capture_tree P_((OnigRegion* region)); -ONIG_EXTERN -int onig_capture_tree_traverse P_((OnigRegion* region, int at, int(*callback_func)(int,int,int,int,int,void*), void* arg)); -ONIG_EXTERN -int onig_noname_group_capture_is_active P_((OnigRegex reg)); -ONIG_EXTERN -OnigEncoding onig_get_encoding P_((OnigRegex reg)); -ONIG_EXTERN -OnigOptionType onig_get_options P_((OnigRegex reg)); -ONIG_EXTERN -OnigCaseFoldType onig_get_case_fold_flag P_((OnigRegex reg)); -ONIG_EXTERN -OnigSyntaxType* onig_get_syntax P_((OnigRegex reg)); -ONIG_EXTERN -int onig_set_default_syntax P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -void onig_copy_syntax P_((OnigSyntaxType* to, OnigSyntaxType* from)); -ONIG_EXTERN -unsigned int onig_get_syntax_op P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -unsigned int onig_get_syntax_op2 P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -unsigned int onig_get_syntax_behavior P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -OnigOptionType onig_get_syntax_options P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -void onig_set_syntax_op P_((OnigSyntaxType* syntax, unsigned int op)); -ONIG_EXTERN -void onig_set_syntax_op2 P_((OnigSyntaxType* syntax, unsigned int op2)); -ONIG_EXTERN -void onig_set_syntax_behavior P_((OnigSyntaxType* syntax, unsigned int behavior)); -ONIG_EXTERN -void onig_set_syntax_options P_((OnigSyntaxType* syntax, OnigOptionType options)); -ONIG_EXTERN -int onig_set_meta_char P_((OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code)); -ONIG_EXTERN -void onig_copy_encoding P_((OnigEncoding to, OnigEncoding from)); -ONIG_EXTERN -OnigCaseFoldType onig_get_default_case_fold_flag P_((void)); -ONIG_EXTERN -int onig_set_default_case_fold_flag P_((OnigCaseFoldType case_fold_flag)); -ONIG_EXTERN -unsigned int onig_get_match_stack_limit_size P_((void)); -ONIG_EXTERN -int onig_set_match_stack_limit_size P_((unsigned int size)); -ONIG_EXTERN -int onig_end P_((void)); -ONIG_EXTERN -const char* onig_version P_((void)); -ONIG_EXTERN -const char* onig_copyright P_((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ONIGURUMA_H */ diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/A/Resources/English.lproj/InfoPlist.strings b/native/frameworks/CocoaOniguruma.framework/Versions/A/Resources/English.lproj/InfoPlist.strings deleted file mode 100644 index 39d5b82c7..000000000 Binary files a/native/frameworks/CocoaOniguruma.framework/Versions/A/Resources/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/A/Resources/Info.plist b/native/frameworks/CocoaOniguruma.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index ccdedf455..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - BuildMachineOSBuild - 11E2620 - CFBundleDevelopmentRegion - English - CFBundleExecutable - CocoaOniguruma - CFBundleIdentifier - net.limechat.CocoaOniguruma - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - CocoaOniguruma - CFBundlePackageType - FMWK - CFBundleSignature - ???? - CFBundleVersion - 1.0 - DTCompiler - - DTPlatformBuild - 4E3002 - DTPlatformVersion - GM - DTSDKBuild - 11E2620 - DTSDKName - - DTXcode - 0433 - DTXcodeBuild - 4E3002 - - diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/Current/CocoaOniguruma b/native/frameworks/CocoaOniguruma.framework/Versions/Current/CocoaOniguruma deleted file mode 100755 index 3799f6f6b..000000000 Binary files a/native/frameworks/CocoaOniguruma.framework/Versions/Current/CocoaOniguruma and /dev/null differ diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/OnigRegexp.h b/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/OnigRegexp.h deleted file mode 100644 index 84f24b46d..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/OnigRegexp.h +++ /dev/null @@ -1,91 +0,0 @@ -// CocoaOniguruma is copyrighted free software by Satoshi Nakagawa . -// You can redistribute it and/or modify it under the new BSD license. - -#import -#import "oniguruma.h" -#import "OnigRegexpUtility.h" - - -@class OnigResult; - -typedef enum { - OnigOptionNone = ONIG_OPTION_NONE, - OnigOptionIgnorecase = ONIG_OPTION_IGNORECASE, - OnigOptionExtend = ONIG_OPTION_EXTEND, - OnigOptionMultiline = ONIG_OPTION_MULTILINE, - OnigOptionSingleline = ONIG_OPTION_SINGLELINE, - OnigOptionFindLongest = ONIG_OPTION_FIND_LONGEST, - OnigOptionFindNotEmpty = ONIG_OPTION_FIND_NOT_EMPTY, - OnigOptionNegateSingleLine = ONIG_OPTION_NEGATE_SINGLELINE, - OnigOptionDontCaptureGroup = ONIG_OPTION_DONT_CAPTURE_GROUP, - OnigOptionCaptureGroup = ONIG_OPTION_CAPTURE_GROUP, - - /* options (search time) */ - OnigOptionNotbol = ONIG_OPTION_NOTBOL, - OnigOptionNoteol = ONIG_OPTION_NOTEOL, - OnigOptionPosixRegion = ONIG_OPTION_POSIX_REGION, - OnigOptionMaxbit = ONIG_OPTION_MAXBIT -} OnigOption; - -@interface OnigRegexp : NSObject -{ - regex_t* _entity; - NSString* _expression; -} - -+ (OnigRegexp*)compile:(NSString*)expression; -+ (OnigRegexp*)compile:(NSString*)expression error:(NSError **)error; -+ (OnigRegexp*)compileIgnorecase:(NSString*)expression; -+ (OnigRegexp*)compileIgnorecase:(NSString*)expression error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline extended:(BOOL)extended; -+ (OnigRegexp*)compile:(NSString*)expression ignorecase:(BOOL)ignorecase multiline:(BOOL)multiline extended:(BOOL)extended error:(NSError **)error; -+ (OnigRegexp*)compile:(NSString*)expression options:(OnigOption)options; -+ (OnigRegexp*)compile:(NSString*)expression options:(OnigOption)options error:(NSError **)error; - -- (OnigResult*)search:(NSString*)target; -- (OnigResult*)search:(NSString*)target start:(int)start; -- (OnigResult*)search:(NSString*)target start:(int)start end:(int)end; -- (OnigResult*)search:(NSString*)target range:(NSRange)range; - -- (OnigResult*)match:(NSString*)target; -- (OnigResult*)match:(NSString*)target start:(int)start; - -- (NSUInteger)captureCount; -- (NSString*)expression; - -@end - - -@interface OnigResult : NSObject -{ - OnigRegexp* _expression; - OnigRegion* _region; - NSString* _target; - NSMutableArray* _captureNames; -} - -- (NSString*)target; - -- (int)count; -- (NSString*)stringAt:(int)index; -- (NSArray*)strings; -- (NSRange)rangeAt:(int)index; -- (int)locationAt:(int)index; -- (int)lengthAt:(int)index; - -- (NSString*)body; -- (NSRange)bodyRange; - -- (NSString*)preMatch; -- (NSString*)postMatch; - -// named capture support -- (NSArray*)captureNames; -- (int)indexForName:(NSString*)name; -- (NSIndexSet*)indexesForName:(NSString*)name; -- (NSString*)stringForName:(NSString*)name; -- (NSArray*)stringsForName:(NSString*)name; - -@end diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/OnigRegexpUtility.h b/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/OnigRegexpUtility.h deleted file mode 100644 index 245ebae3d..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/OnigRegexpUtility.h +++ /dev/null @@ -1,57 +0,0 @@ -// CocoaOniguruma is copyrighted free software by Satoshi Nakagawa . -// You can redistribute it and/or modify it under the new BSD license. - -#import -#import "oniguruma.h" -#import "OnigRegexp.h" - - -@class OnigRegexp; -@class OnigResult; - - -@interface NSString (OnigRegexpUtility) - -// pattern is OnigRegexp or NSString - -- (NSRange)rangeOfRegexp:(id)pattern; - -// based on ruby's split - -- (NSArray*)split; -- (NSArray*)splitByRegexp:(id)pattern; -- (NSArray*)splitByRegexp:(id)pattern limit:(int)limit; - -// based on ruby's gsub - -- (NSString*)replaceByRegexp:(id)pattern with:(NSString*)string; -- (NSString*)replaceAllByRegexp:(id)pattern with:(NSString*)string; - -- (NSString*)replaceByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; -- (NSString*)replaceAllByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; - -#if defined(NS_BLOCKS_AVAILABLE) -- (NSString*)replaceByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -- (NSString*)replaceAllByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -#endif - -@end - - -@interface NSMutableString (OnigRegexpUtility) - -// pattern is OnigRegexp or NSString - -// based on ruby's gsub - -- (NSMutableString*)replaceByRegexp:(id)pattern with:(NSString*)string; -- (NSMutableString*)replaceAllByRegexp:(id)pattern with:(NSString*)string; - -- (NSMutableString*)replaceByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; -- (NSMutableString*)replaceAllByRegexp:(id)pattern withCallback:(id)object selector:(SEL)sel; - -#if defined(NS_BLOCKS_AVAILABLE) -- (NSMutableString*)replaceByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -- (NSMutableString*)replaceAllByRegexp:(id)pattern withBlock:(NSString* (^)(OnigResult*))block; -#endif -@end diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/oniguruma.h b/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/oniguruma.h deleted file mode 100644 index 8c6322c9b..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Headers/oniguruma.h +++ /dev/null @@ -1,770 +0,0 @@ -#ifndef ONIGURUMA_H -#define ONIGURUMA_H -/********************************************************************** - oniguruma.h - Oniguruma (regular expression library) -**********************************************************************/ -/*- - * Copyright (c) 2002-2009 K.Kosako - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define ONIGURUMA -#define ONIGURUMA_VERSION_MAJOR 5 -#define ONIGURUMA_VERSION_MINOR 9 -#define ONIGURUMA_VERSION_TEENY 2 - -#ifdef __cplusplus -# ifndef HAVE_PROTOTYPES -# define HAVE_PROTOTYPES 1 -# endif -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -/* escape Mac OS X/Xcode 2.4/gcc 4.0.1 problem */ -#if defined(__APPLE__) && defined(__GNUC__) && __GNUC__ >= 4 -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -#ifdef HAVE_STDARG_H -# ifndef HAVE_STDARG_PROTOTYPES -# define HAVE_STDARG_PROTOTYPES 1 -# endif -#endif - -#ifndef P_ -#if defined(__STDC__) || defined(_WIN32) -# define P_(args) args -#else -# define P_(args) () -#endif -#endif - -#ifndef PV_ -#ifdef HAVE_STDARG_PROTOTYPES -# define PV_(args) args -#else -# define PV_(args) () -#endif -#endif - -#ifndef ONIG_EXTERN -#if defined(_WIN32) && !defined(__GNUC__) -#if defined(EXPORT) || defined(RUBY_EXPORT) -#define ONIG_EXTERN extern __declspec(dllexport) -#else -#define ONIG_EXTERN extern __declspec(dllimport) -#endif -#endif -#endif - -#ifndef ONIG_EXTERN -#define ONIG_EXTERN extern -#endif - -/* PART: character encoding */ - -#ifndef ONIG_ESCAPE_UCHAR_COLLISION -#define UChar OnigUChar -#endif - -typedef unsigned char OnigUChar; -typedef unsigned long OnigCodePoint; -typedef unsigned int OnigCtype; -typedef unsigned int OnigDistance; - -#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0) - -typedef unsigned int OnigCaseFoldType; /* case fold flag */ - -ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag; - -/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA (1<<1) */ -/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH (1<<2) */ -#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20) -#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30) - -#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR -#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag - - -#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3 -#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13 -/* 13 => Unicode:0x1ffc */ - -/* code range */ -#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0]) -#define ONIGENC_CODE_RANGE_FROM(range,i) range[((i)*2) + 1] -#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2] - -typedef struct { - int byte_len; /* argument(original) character(s) byte length */ - int code_len; /* number of code */ - OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN]; -} OnigCaseFoldCodeItem; - -typedef struct { - OnigCodePoint esc; - OnigCodePoint anychar; - OnigCodePoint anytime; - OnigCodePoint zero_or_one_time; - OnigCodePoint one_or_more_time; - OnigCodePoint anychar_anytime; -} OnigMetaCharTableType; - -typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg); - -typedef struct OnigEncodingTypeST { - int (*mbc_enc_len)(const OnigUChar* p); - const char* name; - int max_enc_len; - int min_enc_len; - int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end); - OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end); - int (*code_to_mbclen)(OnigCodePoint code); - int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf); - int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to); - int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg); - int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[]); - int (*property_name_to_ctype)(struct OnigEncodingTypeST* enc, OnigUChar* p, OnigUChar* end); - int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype); - int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[]); - OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p); - int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end); -} OnigEncodingType; - -typedef OnigEncodingType* OnigEncoding; - -ONIG_EXTERN OnigEncodingType OnigEncodingASCII; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_BE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF16_LE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_BE; -ONIG_EXTERN OnigEncodingType OnigEncodingUTF32_LE; - -#define ONIG_ENCODING_ASCII (&OnigEncodingASCII) -#define ONIG_ENCODING_UTF16_BE (&OnigEncodingUTF16_BE) -#define ONIG_ENCODING_UTF16_LE (&OnigEncodingUTF16_LE) -#define ONIG_ENCODING_UTF32_BE (&OnigEncodingUTF32_BE) -#define ONIG_ENCODING_UTF32_LE (&OnigEncodingUTF32_LE) - -#define ONIG_ENCODING_UNDEF ((OnigEncoding )0) - - -/* work size */ -#define ONIGENC_CODE_TO_MBC_MAXLEN 7 -#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18 -/* 18: 6(max-byte) * 3(case-fold chars) */ - -/* character types */ -#define ONIGENC_CTYPE_NEWLINE 0 -#define ONIGENC_CTYPE_ALPHA 1 -#define ONIGENC_CTYPE_BLANK 2 -#define ONIGENC_CTYPE_CNTRL 3 -#define ONIGENC_CTYPE_DIGIT 4 -#define ONIGENC_CTYPE_GRAPH 5 -#define ONIGENC_CTYPE_LOWER 6 -#define ONIGENC_CTYPE_PRINT 7 -#define ONIGENC_CTYPE_PUNCT 8 -#define ONIGENC_CTYPE_SPACE 9 -#define ONIGENC_CTYPE_UPPER 10 -#define ONIGENC_CTYPE_XDIGIT 11 -#define ONIGENC_CTYPE_WORD 12 -#define ONIGENC_CTYPE_ALNUM 13 /* alpha || digit */ -#define ONIGENC_CTYPE_ASCII 14 -#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII - - -#define onig_enc_len(enc,p,end) ONIGENC_MBC_ENC_LEN(enc,p) - -#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF) -#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1) -#define ONIGENC_IS_MBC_HEAD(enc,p) (ONIGENC_MBC_ENC_LEN(enc,p) != 1) -#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128) -#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128) -#define ONIGENC_IS_MBC_WORD(enc,s,end) \ - ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end)) - - -#define ONIGENC_NAME(enc) ((enc)->name) - -#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \ - (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf) -#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \ - (enc)->is_allowed_reverse_match(s,end) -#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \ - (enc)->left_adjust_char_head(start, s) -#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \ - (enc)->apply_all_case_fold(case_fold_flag,f,arg) -#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \ - (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs) -#define ONIGENC_STEP_BACK(enc,start,s,n) \ - onigenc_step_back((enc),(start),(s),(n)) - -#define ONIGENC_MBC_ENC_LEN(enc,p) (enc)->mbc_enc_len(p) -#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len) -#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc) -#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len) -#define ONIGENC_IS_MBC_NEWLINE(enc,p,end) (enc)->is_mbc_newline((p),(end)) -#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end)) -#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code) -#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf) -#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \ - (enc)->property_name_to_ctype(enc,p,end) - -#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype) - -#define ONIGENC_IS_CODE_NEWLINE(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE) -#define ONIGENC_IS_CODE_GRAPH(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH) -#define ONIGENC_IS_CODE_PRINT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT) -#define ONIGENC_IS_CODE_ALNUM(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM) -#define ONIGENC_IS_CODE_ALPHA(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA) -#define ONIGENC_IS_CODE_LOWER(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER) -#define ONIGENC_IS_CODE_UPPER(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER) -#define ONIGENC_IS_CODE_CNTRL(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL) -#define ONIGENC_IS_CODE_PUNCT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT) -#define ONIGENC_IS_CODE_SPACE(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE) -#define ONIGENC_IS_CODE_BLANK(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK) -#define ONIGENC_IS_CODE_DIGIT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT) -#define ONIGENC_IS_CODE_XDIGIT(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT) -#define ONIGENC_IS_CODE_WORD(enc,code) \ - ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD) - -#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \ - (enc)->get_ctype_code_range(ctype,sbout,ranges) - -ONIG_EXTERN -OnigUChar* onigenc_step_back P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, int n)); - - -/* encoding API */ -ONIG_EXTERN -int onigenc_init P_((void)); -ONIG_EXTERN -int onigenc_set_default_encoding P_((OnigEncoding enc)); -ONIG_EXTERN -OnigEncoding onigenc_get_default_encoding P_((void)); -ONIG_EXTERN -void onigenc_set_default_caseconv_table P_((const OnigUChar* table)); -ONIG_EXTERN -OnigUChar* onigenc_get_right_adjust_char_head_with_prev P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar** prev)); -ONIG_EXTERN -OnigUChar* onigenc_get_prev_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -OnigUChar* onigenc_get_left_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -OnigUChar* onigenc_get_right_adjust_char_head P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s)); -ONIG_EXTERN -int onigenc_strlen P_((OnigEncoding enc, const OnigUChar* p, const OnigUChar* end)); -ONIG_EXTERN -int onigenc_strlen_null P_((OnigEncoding enc, const OnigUChar* p)); -ONIG_EXTERN -int onigenc_str_bytelen_null P_((OnigEncoding enc, const OnigUChar* p)); - - - -/* PART: regular expression */ - -/* config parameters */ -#define ONIG_NREGION 10 -#define ONIG_MAX_BACKREF_NUM 1000 -#define ONIG_MAX_REPEAT_NUM 100000 -#define ONIG_MAX_MULTI_BYTE_RANGES_NUM 10000 -/* constants */ -#define ONIG_MAX_ERROR_MESSAGE_LEN 90 - -typedef unsigned int OnigOptionType; - -#define ONIG_OPTION_DEFAULT ONIG_OPTION_NONE - -/* options */ -#define ONIG_OPTION_NONE 0U -#define ONIG_OPTION_IGNORECASE 1U -#define ONIG_OPTION_EXTEND (ONIG_OPTION_IGNORECASE << 1) -#define ONIG_OPTION_MULTILINE (ONIG_OPTION_EXTEND << 1) -#define ONIG_OPTION_SINGLELINE (ONIG_OPTION_MULTILINE << 1) -#define ONIG_OPTION_FIND_LONGEST (ONIG_OPTION_SINGLELINE << 1) -#define ONIG_OPTION_FIND_NOT_EMPTY (ONIG_OPTION_FIND_LONGEST << 1) -#define ONIG_OPTION_NEGATE_SINGLELINE (ONIG_OPTION_FIND_NOT_EMPTY << 1) -#define ONIG_OPTION_DONT_CAPTURE_GROUP (ONIG_OPTION_NEGATE_SINGLELINE << 1) -#define ONIG_OPTION_CAPTURE_GROUP (ONIG_OPTION_DONT_CAPTURE_GROUP << 1) -/* options (search time) */ -#define ONIG_OPTION_NOTBOL (ONIG_OPTION_CAPTURE_GROUP << 1) -#define ONIG_OPTION_NOTEOL (ONIG_OPTION_NOTBOL << 1) -#define ONIG_OPTION_POSIX_REGION (ONIG_OPTION_NOTEOL << 1) -#define ONIG_OPTION_MAXBIT ONIG_OPTION_POSIX_REGION /* limit */ - -#define ONIG_OPTION_ON(options,regopt) ((options) |= (regopt)) -#define ONIG_OPTION_OFF(options,regopt) ((options) &= ~(regopt)) -#define ONIG_IS_OPTION_ON(options,option) ((options) & (option)) - -/* syntax */ -typedef struct { - unsigned int op; - unsigned int op2; - unsigned int behavior; - OnigOptionType options; /* default option */ - OnigMetaCharTableType meta_char_table; -} OnigSyntaxType; - -ONIG_EXTERN OnigSyntaxType OnigSyntaxASIS; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixBasic; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPosixExtended; -ONIG_EXTERN OnigSyntaxType OnigSyntaxEmacs; -ONIG_EXTERN OnigSyntaxType OnigSyntaxGrep; -ONIG_EXTERN OnigSyntaxType OnigSyntaxGnuRegex; -ONIG_EXTERN OnigSyntaxType OnigSyntaxJava; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl; -ONIG_EXTERN OnigSyntaxType OnigSyntaxPerl_NG; -ONIG_EXTERN OnigSyntaxType OnigSyntaxRuby; - -/* predefined syntaxes (see regsyntax.c) */ -#define ONIG_SYNTAX_ASIS (&OnigSyntaxASIS) -#define ONIG_SYNTAX_POSIX_BASIC (&OnigSyntaxPosixBasic) -#define ONIG_SYNTAX_POSIX_EXTENDED (&OnigSyntaxPosixExtended) -#define ONIG_SYNTAX_EMACS (&OnigSyntaxEmacs) -#define ONIG_SYNTAX_GREP (&OnigSyntaxGrep) -#define ONIG_SYNTAX_GNU_REGEX (&OnigSyntaxGnuRegex) -#define ONIG_SYNTAX_JAVA (&OnigSyntaxJava) -#define ONIG_SYNTAX_PERL (&OnigSyntaxPerl) -#define ONIG_SYNTAX_PERL_NG (&OnigSyntaxPerl_NG) -#define ONIG_SYNTAX_RUBY (&OnigSyntaxRuby) - -/* default syntax */ -ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax; -#define ONIG_SYNTAX_DEFAULT OnigDefaultSyntax - -/* syntax (operators) */ -#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS (1U<<0) -#define ONIG_SYN_OP_DOT_ANYCHAR (1U<<1) /* . */ -#define ONIG_SYN_OP_ASTERISK_ZERO_INF (1U<<2) /* * */ -#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF (1U<<3) -#define ONIG_SYN_OP_PLUS_ONE_INF (1U<<4) /* + */ -#define ONIG_SYN_OP_ESC_PLUS_ONE_INF (1U<<5) -#define ONIG_SYN_OP_QMARK_ZERO_ONE (1U<<6) /* ? */ -#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE (1U<<7) -#define ONIG_SYN_OP_BRACE_INTERVAL (1U<<8) /* {lower,upper} */ -#define ONIG_SYN_OP_ESC_BRACE_INTERVAL (1U<<9) /* \{lower,upper\} */ -#define ONIG_SYN_OP_VBAR_ALT (1U<<10) /* | */ -#define ONIG_SYN_OP_ESC_VBAR_ALT (1U<<11) /* \| */ -#define ONIG_SYN_OP_LPAREN_SUBEXP (1U<<12) /* (...) */ -#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP (1U<<13) /* \(...\) */ -#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR (1U<<14) /* \A, \Z, \z */ -#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR (1U<<15) /* \G */ -#define ONIG_SYN_OP_DECIMAL_BACKREF (1U<<16) /* \num */ -#define ONIG_SYN_OP_BRACKET_CC (1U<<17) /* [...] */ -#define ONIG_SYN_OP_ESC_W_WORD (1U<<18) /* \w, \W */ -#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END (1U<<19) /* \<. \> */ -#define ONIG_SYN_OP_ESC_B_WORD_BOUND (1U<<20) /* \b, \B */ -#define ONIG_SYN_OP_ESC_S_WHITE_SPACE (1U<<21) /* \s, \S */ -#define ONIG_SYN_OP_ESC_D_DIGIT (1U<<22) /* \d, \D */ -#define ONIG_SYN_OP_LINE_ANCHOR (1U<<23) /* ^, $ */ -#define ONIG_SYN_OP_POSIX_BRACKET (1U<<24) /* [:xxxx:] */ -#define ONIG_SYN_OP_QMARK_NON_GREEDY (1U<<25) /* ??,*?,+?,{n,m}? */ -#define ONIG_SYN_OP_ESC_CONTROL_CHARS (1U<<26) /* \n,\r,\t,\a ... */ -#define ONIG_SYN_OP_ESC_C_CONTROL (1U<<27) /* \cx */ -#define ONIG_SYN_OP_ESC_OCTAL3 (1U<<28) /* \OOO */ -#define ONIG_SYN_OP_ESC_X_HEX2 (1U<<29) /* \xHH */ -#define ONIG_SYN_OP_ESC_X_BRACE_HEX8 (1U<<30) /* \x{7HHHHHHH} */ - -#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE (1U<<0) /* \Q...\E */ -#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT (1U<<1) /* (?...) */ -#define ONIG_SYN_OP2_OPTION_PERL (1U<<2) /* (?imsx),(?-imsx) */ -#define ONIG_SYN_OP2_OPTION_RUBY (1U<<3) /* (?imx), (?-imx) */ -#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT (1U<<4) /* ?+,*+,++ */ -#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL (1U<<5) /* {n,m}+ */ -#define ONIG_SYN_OP2_CCLASS_SET_OP (1U<<6) /* [...&&..[..]..] */ -#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP (1U<<7) /* (?...) */ -#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF (1U<<8) /* \k */ -#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL (1U<<9) /* \g, \g */ -#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY (1U<<10) /* (?@..),(?@..) */ -#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL (1U<<11) /* \C-x */ -#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META (1U<<12) /* \M-x */ -#define ONIG_SYN_OP2_ESC_V_VTAB (1U<<13) /* \v as VTAB */ -#define ONIG_SYN_OP2_ESC_U_HEX4 (1U<<14) /* \uHHHH */ -#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15) /* \`, \' */ -#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16) /* \p{...}, \P{...} */ -#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */ -/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */ -#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19) /* \h, \H */ -#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20) /* \ */ - -/* syntax (behavior) */ -#define ONIG_SYN_CONTEXT_INDEP_ANCHORS (1U<<31) /* not implemented */ -#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS (1U<<0) /* ?, *, +, {n,m} */ -#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS (1U<<1) /* error or ignore */ -#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP (1U<<2) /* ...)... */ -#define ONIG_SYN_ALLOW_INVALID_INTERVAL (1U<<3) /* {??? */ -#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV (1U<<4) /* {,n} => {0,n} */ -#define ONIG_SYN_STRICT_CHECK_BACKREF (1U<<5) /* /(\1)/,/\1()/ ..*/ -#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND (1U<<6) /* (?<=a|bc) */ -#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP (1U<<7) /* see doc/RE */ -#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8) /* (?)(?) */ -#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY (1U<<9) /* a{n}?=(?:a{n})? */ - -/* syntax (behavior) in char class [...] */ -#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC (1U<<20) /* [^...] */ -#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC (1U<<21) /* [..\w..] etc.. */ -#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC (1U<<22) -#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC (1U<<23) /* [0-9-a]=[0-9\-a] */ -/* syntax (behavior) warning */ -#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED (1U<<24) /* [,-,] */ -#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT (1U<<25) /* (?:a*)+ */ - -/* meta character specifiers (onig_set_meta_char()) */ -#define ONIG_META_CHAR_ESCAPE 0 -#define ONIG_META_CHAR_ANYCHAR 1 -#define ONIG_META_CHAR_ANYTIME 2 -#define ONIG_META_CHAR_ZERO_OR_ONE_TIME 3 -#define ONIG_META_CHAR_ONE_OR_MORE_TIME 4 -#define ONIG_META_CHAR_ANYCHAR_ANYTIME 5 - -#define ONIG_INEFFECTIVE_META_CHAR 0 - -/* error codes */ -#define ONIG_IS_PATTERN_ERROR(ecode) ((ecode) <= -100 && (ecode) > -1000) -/* normal return */ -#define ONIG_NORMAL 0 -#define ONIG_MISMATCH -1 -#define ONIG_NO_SUPPORT_CONFIG -2 - -/* internal error */ -#define ONIGERR_MEMORY -5 -#define ONIGERR_TYPE_BUG -6 -#define ONIGERR_PARSER_BUG -11 -#define ONIGERR_STACK_BUG -12 -#define ONIGERR_UNDEFINED_BYTECODE -13 -#define ONIGERR_UNEXPECTED_BYTECODE -14 -#define ONIGERR_MATCH_STACK_LIMIT_OVER -15 -#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED -21 -#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22 -/* general error */ -#define ONIGERR_INVALID_ARGUMENT -30 -/* syntax error */ -#define ONIGERR_END_PATTERN_AT_LEFT_BRACE -100 -#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET -101 -#define ONIGERR_EMPTY_CHAR_CLASS -102 -#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS -103 -#define ONIGERR_END_PATTERN_AT_ESCAPE -104 -#define ONIGERR_END_PATTERN_AT_META -105 -#define ONIGERR_END_PATTERN_AT_CONTROL -106 -#define ONIGERR_META_CODE_SYNTAX -108 -#define ONIGERR_CONTROL_CODE_SYNTAX -109 -#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE -110 -#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE -111 -#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS -112 -#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED -113 -#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID -114 -#define ONIGERR_NESTED_REPEAT_OPERATOR -115 -#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS -116 -#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS -117 -#define ONIGERR_END_PATTERN_IN_GROUP -118 -#define ONIGERR_UNDEFINED_GROUP_OPTION -119 -#define ONIGERR_INVALID_POSIX_BRACKET_TYPE -121 -#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN -122 -#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN -123 -/* values error (syntax error) */ -#define ONIGERR_TOO_BIG_NUMBER -200 -#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE -201 -#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE -202 -#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS -203 -#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE -204 -#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES -205 -#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING -206 -#define ONIGERR_TOO_BIG_BACKREF_NUMBER -207 -#define ONIGERR_INVALID_BACKREF -208 -#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED -209 -#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE -212 -#define ONIGERR_EMPTY_GROUP_NAME -214 -#define ONIGERR_INVALID_GROUP_NAME -215 -#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME -216 -#define ONIGERR_UNDEFINED_NAME_REFERENCE -217 -#define ONIGERR_UNDEFINED_GROUP_REFERENCE -218 -#define ONIGERR_MULTIPLEX_DEFINED_NAME -219 -#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL -220 -#define ONIGERR_NEVER_ENDING_RECURSION -221 -#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222 -#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223 -#define ONIGERR_INVALID_CODE_POINT_VALUE -400 -#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400 -#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401 -#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402 -#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS -403 - -/* errors related to thread */ -#define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT -1001 - - -/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */ -#define ONIG_MAX_CAPTURE_HISTORY_GROUP 31 -#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \ - ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i]) - -typedef struct OnigCaptureTreeNodeStruct { - int group; /* group number */ - int beg; - int end; - int allocated; - int num_childs; - struct OnigCaptureTreeNodeStruct** childs; -} OnigCaptureTreeNode; - -/* match result region type */ -struct re_registers { - int allocated; - int num_regs; - int* beg; - int* end; - /* extended */ - OnigCaptureTreeNode* history_root; /* capture history tree root */ -}; - -/* capture tree traverse */ -#define ONIG_TRAVERSE_CALLBACK_AT_FIRST 1 -#define ONIG_TRAVERSE_CALLBACK_AT_LAST 2 -#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \ - ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST ) - - -#define ONIG_REGION_NOTPOS -1 - -typedef struct re_registers OnigRegion; - -typedef struct { - OnigEncoding enc; - OnigUChar* par; - OnigUChar* par_end; -} OnigErrorInfo; - -typedef struct { - int lower; - int upper; -} OnigRepeatRange; - -typedef void (*OnigWarnFunc) P_((const char* s)); -extern void onig_null_warn P_((const char* s)); -#define ONIG_NULL_WARN onig_null_warn - -#define ONIG_CHAR_TABLE_SIZE 256 - -/* regex_t state */ -#define ONIG_STATE_NORMAL 0 -#define ONIG_STATE_SEARCHING 1 -#define ONIG_STATE_COMPILING -1 -#define ONIG_STATE_MODIFY -2 - -#define ONIG_STATE(reg) \ - ((reg)->state > 0 ? ONIG_STATE_SEARCHING : (reg)->state) - -typedef struct re_pattern_buffer { - /* common members of BBuf(bytes-buffer) */ - unsigned char* p; /* compiled pattern */ - unsigned int used; /* used space for p */ - unsigned int alloc; /* allocated space for p */ - - int state; /* normal, searching, compiling */ - int num_mem; /* used memory(...) num counted from 1 */ - int num_repeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */ - int num_null_check; /* OP_NULL_CHECK_START/END id counter */ - int num_comb_exp_check; /* combination explosion check */ - int num_call; /* number of subexp call */ - unsigned int capture_history; /* (?@...) flag (1-31) */ - unsigned int bt_mem_start; /* need backtrack flag */ - unsigned int bt_mem_end; /* need backtrack flag */ - int stack_pop_level; - int repeat_range_alloc; - OnigRepeatRange* repeat_range; - - OnigEncoding enc; - OnigOptionType options; - OnigSyntaxType* syntax; - OnigCaseFoldType case_fold_flag; - void* name_table; - - /* optimization info (string search, char-map and anchors) */ - int optimize; /* optimize flag */ - int threshold_len; /* search str-length for apply optimize */ - int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */ - OnigDistance anchor_dmin; /* (SEMI_)END_BUF anchor distance */ - OnigDistance anchor_dmax; /* (SEMI_)END_BUF anchor distance */ - int sub_anchor; /* start-anchor for exact or map */ - unsigned char *exact; - unsigned char *exact_end; - unsigned char map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */ - int *int_map; /* BM skip for exact_len > 255 */ - int *int_map_backward; /* BM skip for backward search */ - OnigDistance dmin; /* min-distance of exact or map */ - OnigDistance dmax; /* max-distance of exact or map */ - - /* regex_t link chain */ - struct re_pattern_buffer* chain; /* escape compile-conflict */ -} OnigRegexType; - -typedef OnigRegexType* OnigRegex; - -#ifndef ONIG_ESCAPE_REGEX_T_COLLISION - typedef OnigRegexType regex_t; -#endif - - -typedef struct { - int num_of_elements; - OnigEncoding pattern_enc; - OnigEncoding target_enc; - OnigSyntaxType* syntax; - OnigOptionType option; - OnigCaseFoldType case_fold_flag; -} OnigCompileInfo; - -/* Oniguruma Native API */ -ONIG_EXTERN -int onig_init P_((void)); -ONIG_EXTERN -int onig_error_code_to_str PV_((OnigUChar* s, int err_code, ...)); -ONIG_EXTERN -void onig_set_warn_func P_((OnigWarnFunc f)); -ONIG_EXTERN -void onig_set_verb_warn_func P_((OnigWarnFunc f)); -ONIG_EXTERN -int onig_new P_((OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_reg_init P_((regex_t* reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, OnigSyntaxType* syntax)); -int onig_new_without_alloc P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_new_deluxe P_((OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo)); -ONIG_EXTERN -void onig_free P_((OnigRegex)); -ONIG_EXTERN -void onig_free_body P_((OnigRegex)); -ONIG_EXTERN -int onig_recompile P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_recompile_deluxe P_((OnigRegex reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo)); -ONIG_EXTERN -int onig_search P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option)); -ONIG_EXTERN -int onig_match P_((OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option)); -ONIG_EXTERN -OnigRegion* onig_region_new P_((void)); -ONIG_EXTERN -void onig_region_init P_((OnigRegion* region)); -ONIG_EXTERN -void onig_region_free P_((OnigRegion* region, int free_self)); -ONIG_EXTERN -void onig_region_copy P_((OnigRegion* to, OnigRegion* from)); -ONIG_EXTERN -void onig_region_clear P_((OnigRegion* region)); -ONIG_EXTERN -int onig_region_resize P_((OnigRegion* region, int n)); -ONIG_EXTERN -int onig_region_set P_((OnigRegion* region, int at, int beg, int end)); -ONIG_EXTERN -int onig_name_to_group_numbers P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums)); -ONIG_EXTERN -int onig_name_to_backref_number P_((OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, OnigRegion *region)); -ONIG_EXTERN -int onig_foreach_name P_((OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg)); -ONIG_EXTERN -int onig_number_of_names P_((OnigRegex reg)); -ONIG_EXTERN -int onig_number_of_captures P_((OnigRegex reg)); -ONIG_EXTERN -int onig_number_of_capture_histories P_((OnigRegex reg)); -ONIG_EXTERN -OnigCaptureTreeNode* onig_get_capture_tree P_((OnigRegion* region)); -ONIG_EXTERN -int onig_capture_tree_traverse P_((OnigRegion* region, int at, int(*callback_func)(int,int,int,int,int,void*), void* arg)); -ONIG_EXTERN -int onig_noname_group_capture_is_active P_((OnigRegex reg)); -ONIG_EXTERN -OnigEncoding onig_get_encoding P_((OnigRegex reg)); -ONIG_EXTERN -OnigOptionType onig_get_options P_((OnigRegex reg)); -ONIG_EXTERN -OnigCaseFoldType onig_get_case_fold_flag P_((OnigRegex reg)); -ONIG_EXTERN -OnigSyntaxType* onig_get_syntax P_((OnigRegex reg)); -ONIG_EXTERN -int onig_set_default_syntax P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -void onig_copy_syntax P_((OnigSyntaxType* to, OnigSyntaxType* from)); -ONIG_EXTERN -unsigned int onig_get_syntax_op P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -unsigned int onig_get_syntax_op2 P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -unsigned int onig_get_syntax_behavior P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -OnigOptionType onig_get_syntax_options P_((OnigSyntaxType* syntax)); -ONIG_EXTERN -void onig_set_syntax_op P_((OnigSyntaxType* syntax, unsigned int op)); -ONIG_EXTERN -void onig_set_syntax_op2 P_((OnigSyntaxType* syntax, unsigned int op2)); -ONIG_EXTERN -void onig_set_syntax_behavior P_((OnigSyntaxType* syntax, unsigned int behavior)); -ONIG_EXTERN -void onig_set_syntax_options P_((OnigSyntaxType* syntax, OnigOptionType options)); -ONIG_EXTERN -int onig_set_meta_char P_((OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code)); -ONIG_EXTERN -void onig_copy_encoding P_((OnigEncoding to, OnigEncoding from)); -ONIG_EXTERN -OnigCaseFoldType onig_get_default_case_fold_flag P_((void)); -ONIG_EXTERN -int onig_set_default_case_fold_flag P_((OnigCaseFoldType case_fold_flag)); -ONIG_EXTERN -unsigned int onig_get_match_stack_limit_size P_((void)); -ONIG_EXTERN -int onig_set_match_stack_limit_size P_((unsigned int size)); -ONIG_EXTERN -int onig_end P_((void)); -ONIG_EXTERN -const char* onig_version P_((void)); -ONIG_EXTERN -const char* onig_copyright P_((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ONIGURUMA_H */ diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Resources/English.lproj/InfoPlist.strings b/native/frameworks/CocoaOniguruma.framework/Versions/Current/Resources/English.lproj/InfoPlist.strings deleted file mode 100644 index 39d5b82c7..000000000 Binary files a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Resources/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Resources/Info.plist b/native/frameworks/CocoaOniguruma.framework/Versions/Current/Resources/Info.plist deleted file mode 100644 index ccdedf455..000000000 --- a/native/frameworks/CocoaOniguruma.framework/Versions/Current/Resources/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - BuildMachineOSBuild - 11E2620 - CFBundleDevelopmentRegion - English - CFBundleExecutable - CocoaOniguruma - CFBundleIdentifier - net.limechat.CocoaOniguruma - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - CocoaOniguruma - CFBundlePackageType - FMWK - CFBundleSignature - ???? - CFBundleVersion - 1.0 - DTCompiler - - DTPlatformBuild - 4E3002 - DTPlatformVersion - GM - DTSDKBuild - 11E2620 - DTSDKName - - DTXcode - 0433 - DTXcodeBuild - 4E3002 - - diff --git a/native/linux/atom_cef_render_process_handler.cpp b/native/linux/atom_cef_render_process_handler.cpp index 84b66c5ea..33e1d4c73 100644 --- a/native/linux/atom_cef_render_process_handler.cpp +++ b/native/linux/atom_cef_render_process_handler.cpp @@ -9,7 +9,6 @@ void AtomCefRenderProcessHandler::OnWebKitInitialized() { new v8_extensions::Atom(); new v8_extensions::NativeHandler(); - new v8_extensions::OnigRegExp(); } void AtomCefRenderProcessHandler::OnContextCreated( diff --git a/native/mac/Atom-Info.plist b/native/mac/Atom-Info.plist index c295d2e6a..86a352764 100644 --- a/native/mac/Atom-Info.plist +++ b/native/mac/Atom-Info.plist @@ -31,11 +31,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.3 + 2.0 CFBundleSignature ???? CFBundleVersion - 0.3 + 2.0 LSApplicationCategoryType public.app-category.developer-tools NSMainNibFile diff --git a/native/path_watcher.mm b/native/path_watcher.mm index e5cc65afe..47c7dee2f 100644 --- a/native/path_watcher.mm +++ b/native/path_watcher.mm @@ -99,7 +99,6 @@ static NSMutableArray *gPathWatchers; } - (NSString *)watchPath:(NSString *)path callback:(WatchCallback)callback callbackId:(NSString *)callbackId { - path = [path stringByStandardizingPath]; @synchronized(self) { if (![self createKeventForPath:path]) { NSLog(@"WARNING: Failed to create kevent for path '%@'", path); @@ -119,8 +118,6 @@ static NSMutableArray *gPathWatchers; } - (void)unwatchPath:(NSString *)path callbackId:(NSString *)callbackId error:(NSError **)error { - path = [path stringByStandardizingPath]; - @synchronized(self) { NSMutableDictionary *callbacks = [_callbacksByPath objectForKey:path]; @@ -154,8 +151,6 @@ static NSMutableArray *gPathWatchers; } - (bool)createKeventForPath:(NSString *)path { - path = [path stringByStandardizingPath]; - @synchronized(self) { if ([_fileDescriptorsByPath objectForKey:path]) { NSLog(@"we already have a kevent"); @@ -182,8 +177,6 @@ static NSMutableArray *gPathWatchers; } - (void)removeKeventForPath:(NSString *)path { - path = [path stringByStandardizingPath]; - @synchronized(self) { NSNumber *fdNumber = [_fileDescriptorsByPath objectForKey:path]; if (!fdNumber) { @@ -245,7 +238,7 @@ static NSMutableArray *gPathWatchers; char pathBuffer[MAXPATHLEN]; fcntl((int)event.ident, F_GETPATH, &pathBuffer); close(event.ident); - newPath = [[NSString stringWithUTF8String:pathBuffer] stringByStandardizingPath]; + newPath = [NSString stringWithUTF8String:pathBuffer]; if (!newPath) { NSLog(@"WARNING: Ignoring rename event for deleted file '%@'", path); continue; diff --git a/native/v8_extensions/git.h b/native/v8_extensions/git.h deleted file mode 100644 index 74876fe11..000000000 --- a/native/v8_extensions/git.h +++ /dev/null @@ -1,22 +0,0 @@ -#include "include/cef_base.h" -#include "include/cef_v8.h" - -namespace v8_extensions { - class Git : public CefV8Handler { - public: - Git(); - void CreateContextBinding(CefRefPtr context); - virtual bool Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) OVERRIDE; - - // Provide the reference counting implementation for this class. - IMPLEMENT_REFCOUNTING(Git); - - private: - Git(Git const&); - void operator=(Git const&); - }; -} diff --git a/native/v8_extensions/git.mm b/native/v8_extensions/git.mm deleted file mode 100644 index 49aa98bf1..000000000 --- a/native/v8_extensions/git.mm +++ /dev/null @@ -1,493 +0,0 @@ -#import "git.h" -#import "include/git2.h" -#import - -namespace v8_extensions { - - class GitRepository : public CefBase { - private: - git_repository *repo; - - static int CollectStatus(const char *path, unsigned int status, void *payload) { - if ((status & GIT_STATUS_IGNORED) == 0) { - std::map *statuses = (std::map *) payload; - statuses->insert(std::pair(path, status)); - } - return 0; - } - - static int CollectDiffHunk(const git_diff_delta *delta, const git_diff_range *range, - const char *header, size_t header_len, void *payload) { - std::vector *ranges = (std::vector *) payload; - ranges->push_back(*range); - return 0; - } - - public: - GitRepository(const char *pathInRepo) { - if (git_repository_open_ext(&repo, pathInRepo, 0, NULL) != GIT_OK) { - repo = NULL; - } - } - - ~GitRepository() { - Destroy(); - } - - void Destroy() { - if (Exists()) { - git_repository_free(repo); - repo = NULL; - } - } - - BOOL Exists() { - return repo != NULL; - } - - CefRefPtr GetPath() { - return CefV8Value::CreateString(git_repository_path(repo)); - } - - CefRefPtr GetHead() { - git_reference *head; - if (git_repository_head(&head, repo) == GIT_OK) { - if (git_repository_head_detached(repo) == 1) { - const git_oid* sha = git_reference_target(head); - if (sha) { - char oid[GIT_OID_HEXSZ + 1]; - git_oid_tostr(oid, GIT_OID_HEXSZ + 1, sha); - git_reference_free(head); - return CefV8Value::CreateString(oid); - } - } - - CefRefPtr result = CefV8Value::CreateString(git_reference_name(head)); - git_reference_free(head); - return result; - } - - return CefV8Value::CreateNull(); - } - - CefRefPtr GetStatuses() { - std::map statuses; - git_status_foreach(repo, CollectStatus, &statuses); - std::map::iterator iter = statuses.begin(); - CefRefPtr v8Statuses = CefV8Value::CreateObject(NULL); - for (; iter != statuses.end(); ++iter) { - v8Statuses->SetValue(iter->first, CefV8Value::CreateInt(iter->second), V8_PROPERTY_ATTRIBUTE_NONE); - } - return v8Statuses; - } - - int GetCommitCount(const git_oid* fromCommit, const git_oid* toCommit) { - int count = 0; - git_revwalk *revWalk; - if (git_revwalk_new(&revWalk, repo) == GIT_OK) { - git_revwalk_push(revWalk, fromCommit); - git_revwalk_hide(revWalk, toCommit); - git_oid currentCommit; - while (git_revwalk_next(¤tCommit, revWalk) == GIT_OK) - count++; - git_revwalk_free(revWalk); - } - return count; - } - - void GetShortBranchName(const char** out, const char* branchName) { - *out = NULL; - if (branchName == NULL) - return; - int branchNameLength = strlen(branchName); - if (branchNameLength < 12) - return; - if (strncmp("refs/heads/", branchName, 11) != 0) - return; - - int shortNameLength = branchNameLength - 11; - char* shortName = (char*) malloc(sizeof(char) * (shortNameLength + 1)); - shortName[shortNameLength] = '\0'; - strncpy(shortName, &branchName[11], shortNameLength); - *out = shortName; - } - - void GetUpstreamBranch(const char** out, git_reference *branch) { - *out = NULL; - - const char* branchName = git_reference_name(branch); - const char* shortBranchName; - GetShortBranchName(&shortBranchName, branchName); - if (shortBranchName == NULL) - return; - - int shortBranchNameLength = strlen(shortBranchName); - char* remoteKey = (char*) malloc(sizeof(char) * (shortBranchNameLength + 15)); - sprintf(remoteKey, "branch.%s.remote", shortBranchName); - char* mergeKey = (char*) malloc(sizeof(char) * (shortBranchNameLength + 14)); - sprintf(mergeKey, "branch.%s.merge", shortBranchName); - free((char*)shortBranchName); - - git_config *config; - if (git_repository_config(&config, repo) != GIT_OK) { - free(remoteKey); - free(mergeKey); - return; - } - - const char *remote; - const char *merge; - if (git_config_get_string(&remote, config, remoteKey) == GIT_OK - && git_config_get_string(&merge, config, mergeKey) == GIT_OK) { - int remoteLength = strlen(remote); - if (remoteLength > 0) { - const char *shortMergeBranchName; - GetShortBranchName(&shortMergeBranchName, merge); - if (shortMergeBranchName != NULL) { - int updateBranchLength = remoteLength + strlen(shortMergeBranchName) + 14; - char* upstreamBranch = (char*) malloc(sizeof(char) * (updateBranchLength + 1)); - sprintf(upstreamBranch, "refs/remotes/%s/%s", remote, shortMergeBranchName); - *out = upstreamBranch; - } - free((char*)shortMergeBranchName); - } - } - - free(remoteKey); - free(mergeKey); - git_config_free(config); - } - - CefRefPtr GetAheadBehindCounts() { - CefRefPtr result = NULL; - git_reference *head; - if (git_repository_head(&head, repo) == GIT_OK) { - const char* upstreamBranchName; - GetUpstreamBranch(&upstreamBranchName, head); - if (upstreamBranchName != NULL) { - git_reference *upstream; - if (git_reference_lookup(&upstream, repo, upstreamBranchName) == GIT_OK) { - const git_oid* headSha = git_reference_target(head); - const git_oid* upstreamSha = git_reference_target(upstream); - git_oid mergeBase; - if (git_merge_base(&mergeBase, repo, headSha, upstreamSha) == GIT_OK) { - result = CefV8Value::CreateObject(NULL); - int ahead = GetCommitCount(headSha, &mergeBase); - result->SetValue("ahead", CefV8Value::CreateInt(ahead), V8_PROPERTY_ATTRIBUTE_NONE); - int behind = GetCommitCount(upstreamSha, &mergeBase); - result->SetValue("behind", CefV8Value::CreateInt(behind), V8_PROPERTY_ATTRIBUTE_NONE); - } - git_reference_free(upstream); - } - free((char*)upstreamBranchName); - } - git_reference_free(head); - } - - if (result != NULL) - return result; - else - return CefV8Value::CreateNull(); - } - - CefRefPtr IsIgnored(const char *path) { - int ignored; - if (git_ignore_path_is_ignored(&ignored, repo, path) == GIT_OK) { - return CefV8Value::CreateBool(ignored == 1); - } - else { - return CefV8Value::CreateBool(false); - } - } - - CefRefPtr GetStatus(const char *path) { - unsigned int status = 0; - if (git_status_file(&status, repo, path) == GIT_OK) { - return CefV8Value::CreateInt(status); - } - else { - return CefV8Value::CreateInt(0); - } - } - - CefRefPtr CheckoutHead(const char *path) { - char *copiedPath = (char *)malloc(sizeof(char) * (strlen(path) + 1)); - strcpy(copiedPath, path); - git_checkout_opts options = GIT_CHECKOUT_OPTS_INIT; - options.checkout_strategy = GIT_CHECKOUT_FORCE; - git_strarray paths; - paths.count = 1; - paths.strings = &copiedPath; - options.paths = paths; - - int result = git_checkout_head(repo, &options); - free(copiedPath); - return CefV8Value::CreateBool(result == GIT_OK); - } - - CefRefPtr GetDiffStats(const char *path) { - git_reference *head; - if (git_repository_head(&head, repo) != GIT_OK) { - return CefV8Value::CreateNull(); - } - - const git_oid* sha = git_reference_target(head); - git_commit *commit; - int commitStatus = git_commit_lookup(&commit, repo, sha); - git_reference_free(head); - if (commitStatus != GIT_OK) { - return CefV8Value::CreateNull(); - } - - git_tree *tree; - int treeStatus = git_commit_tree(&tree, commit); - git_commit_free(commit); - if (treeStatus != GIT_OK) { - return CefV8Value::CreateNull(); - } - - char *copiedPath = (char *)malloc(sizeof(char) * (strlen(path) + 1)); - strcpy(copiedPath, path); - git_diff_options options = GIT_DIFF_OPTIONS_INIT; - git_strarray paths; - paths.count = 1; - paths.strings = &copiedPath; - options.pathspec = paths; - options.context_lines = 1; - options.flags = GIT_DIFF_DISABLE_PATHSPEC_MATCH; - - git_diff_list *diffs; - int diffStatus = git_diff_tree_to_workdir(&diffs, repo, tree, &options); - git_tree_free(tree); - free(copiedPath); - if (diffStatus != GIT_OK || git_diff_num_deltas(diffs) != 1) { - return CefV8Value::CreateNull(); - } - - git_diff_patch *patch; - int patchStatus = git_diff_get_patch(&patch, NULL, diffs, 0); - git_diff_list_free(diffs); - if (patchStatus != GIT_OK) { - return CefV8Value::CreateNull(); - } - - int added = 0; - int deleted = 0; - int hunks = git_diff_patch_num_hunks(patch); - for (int i = 0; i < hunks; i++) { - int lines = git_diff_patch_num_lines_in_hunk(patch, i); - for (int j = 0; j < lines; j++) { - char lineType; - if (git_diff_patch_get_line_in_hunk(&lineType, NULL, NULL, NULL, NULL, patch, i, j) == GIT_OK) { - switch (lineType) { - case GIT_DIFF_LINE_ADDITION: - added++; - break; - case GIT_DIFF_LINE_DELETION: - deleted++; - break; - } - } - } - } - git_diff_patch_free(patch); - - CefRefPtr result = CefV8Value::CreateObject(NULL); - result->SetValue("added", CefV8Value::CreateInt(added), V8_PROPERTY_ATTRIBUTE_NONE); - result->SetValue("deleted", CefV8Value::CreateInt(deleted), V8_PROPERTY_ATTRIBUTE_NONE); - return result; - } - - CefRefPtr GetLineDiffs(const char *path, const char *text) { - git_reference *head; - if (git_repository_head(&head, repo) != GIT_OK) - return CefV8Value::CreateNull(); - - const git_oid* sha = git_reference_target(head); - git_commit *commit; - int commitStatus = git_commit_lookup(&commit, repo, sha); - git_reference_free(head); - if (commitStatus != GIT_OK) - return CefV8Value::CreateNull(); - - git_tree *tree; - int treeStatus = git_commit_tree(&tree, commit); - git_commit_free(commit); - if (treeStatus != GIT_OK) - return CefV8Value::CreateNull(); - - git_tree_entry* treeEntry; - git_tree_entry_bypath(&treeEntry, tree, path); - git_blob *blob = NULL; - if (treeEntry != NULL) { - const git_oid *blobSha = git_tree_entry_id(treeEntry); - if (blobSha == NULL || git_blob_lookup(&blob, repo, blobSha) != GIT_OK) - blob = NULL; - } - git_tree_free(tree); - if (blob == NULL) - return CefV8Value::CreateNull(); - - int size = strlen(text); - std::vector ranges; - git_diff_options options = GIT_DIFF_OPTIONS_INIT; - options.context_lines = 1; - if (git_diff_blob_to_buffer(blob, text, size, &options, NULL, CollectDiffHunk, NULL, &ranges) == GIT_OK) { - CefRefPtr v8Ranges = CefV8Value::CreateArray(ranges.size()); - for(int i = 0; i < ranges.size(); i++) { - CefRefPtr v8Range = CefV8Value::CreateObject(NULL); - v8Range->SetValue("oldStart", CefV8Value::CreateInt(ranges[i].old_start), V8_PROPERTY_ATTRIBUTE_NONE); - v8Range->SetValue("oldLines", CefV8Value::CreateInt(ranges[i].old_lines), V8_PROPERTY_ATTRIBUTE_NONE); - v8Range->SetValue("newStart", CefV8Value::CreateInt(ranges[i].new_start), V8_PROPERTY_ATTRIBUTE_NONE); - v8Range->SetValue("newLines", CefV8Value::CreateInt(ranges[i].new_lines), V8_PROPERTY_ATTRIBUTE_NONE); - v8Ranges->SetValue(i, v8Range); - } - git_blob_free(blob); - return v8Ranges; - } else { - git_blob_free(blob); - return CefV8Value::CreateNull(); - } - } - - CefRefPtr IsSubmodule(const char *path) { - BOOL isSubmodule = false; - git_index* index; - if (git_repository_index(&index, repo) == GIT_OK) { - const git_index_entry *entry = git_index_get_bypath(index, path, 0); - isSubmodule = entry != NULL && (entry->mode & S_IFMT) == GIT_FILEMODE_COMMIT; - git_index_free(index); - } - return CefV8Value::CreateBool(isSubmodule); - } - - void RefreshIndex() { - git_index* index; - if (git_repository_index(&index, repo) == GIT_OK) { - git_index_read(index); - git_index_free(index); - } - } - - IMPLEMENT_REFCOUNTING(GitRepository); - }; - - Git::Git() : CefV8Handler() { - git_threads_init(); - } - - void Git::CreateContextBinding(CefRefPtr context) { - const char* methodNames[] = { - "getRepository", "getHead", "getPath", "isIgnored", "getStatus", "checkoutHead", - "getDiffStats", "isSubmodule", "refreshIndex", "destroy", "getStatuses", - "getAheadBehindCounts", "getLineDiffs" - }; - - CefRefPtr nativeObject = CefV8Value::CreateObject(NULL); - int arrayLength = sizeof(methodNames) / sizeof(const char *); - for (int i = 0; i < arrayLength; i++) { - const char *functionName = methodNames[i]; - CefRefPtr function = CefV8Value::CreateFunction(functionName, this); - nativeObject->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE); - } - - CefRefPtr global = context->GetGlobal(); - global->SetValue("$git", nativeObject, V8_PROPERTY_ATTRIBUTE_NONE); - } - - bool Git::Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) { - @autoreleasepool { - if (name == "getRepository") { - GitRepository *repository = new GitRepository(arguments[0]->GetStringValue().ToString().c_str()); - if (repository->Exists()) { - CefRefPtr userData = repository; - retval = CefV8Value::CreateObject(NULL); - retval->SetUserData(userData); - } else { - retval = CefV8Value::CreateNull(); - } - return true; - } - - if (name == "getHead") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->GetHead(); - return true; - } - - if (name == "getPath") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->GetPath(); - return true; - } - - if (name == "isIgnored") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->IsIgnored(arguments[0]->GetStringValue().ToString().c_str()); - return true; - } - - if (name == "getStatus") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->GetStatus(arguments[0]->GetStringValue().ToString().c_str()); - return true; - } - - if (name == "checkoutHead") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->CheckoutHead(arguments[0]->GetStringValue().ToString().c_str()); - return true; - } - - if (name == "getDiffStats") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->GetDiffStats(arguments[0]->GetStringValue().ToString().c_str()); - return true; - } - - if (name == "isSubmodule") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->IsSubmodule(arguments[0]->GetStringValue().ToString().c_str()); - return true; - } - - if (name == "refreshIndex") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - userData->RefreshIndex(); - return true; - } - - if (name == "destroy") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - userData->Destroy(); - return true; - } - - if (name == "getStatuses") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->GetStatuses(); - return true; - } - - if (name == "getAheadBehindCounts") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - retval = userData->GetAheadBehindCounts(); - return true; - } - - if (name == "getLineDiffs") { - GitRepository *userData = (GitRepository *)object->GetUserData().get(); - std::string path = arguments[0]->GetStringValue().ToString(); - std::string text = arguments[1]->GetStringValue().ToString(); - retval = userData->GetLineDiffs(path.c_str(), text.c_str()); - return true; - } - - return false; - } - } -} diff --git a/native/v8_extensions/native.mm b/native/v8_extensions/native.mm index b34b68145..03c92eda0 100644 --- a/native/v8_extensions/native.mm +++ b/native/v8_extensions/native.mm @@ -1,6 +1,5 @@ #import #import -#import #import "atom_application.h" #import "native.h" @@ -8,9 +7,8 @@ #import "path_watcher.h" #import -#include -static std::string windowState = "{}"; +static std::string windowState = ""; static NSLock *windowStateLock = [[NSLock alloc] init]; namespace v8_extensions { @@ -24,11 +22,9 @@ namespace v8_extensions { void Native::CreateContextBinding(CefRefPtr context) { const char* methodNames[] = { - "exists", "read", "write", "absolute", "getAllFilePathsAsync", "traverseTree", "isDirectory", - "isFile", "remove", "writeToPasteboard", "readFromPasteboard", "quit", "watchPath", "unwatchPath", - "getWatchedPaths", "unwatchAllPaths", "makeDirectory", "move", "moveToTrash", "reload", "lastModified", - "md5ForPath", "exec", "getPlatform", "setWindowState", "getWindowState", "isMisspelled", - "getCorrectionsForMisspelling" + "writeToPasteboard", "readFromPasteboard", "quit", "watchPath", + "unwatchPath", "getWatchedPaths", "unwatchAllPaths", "moveToTrash", + "reload", "setWindowState", "getWindowState", "beep" }; CefRefPtr nativeObject = CefV8Value::CreateObject(NULL); @@ -49,193 +45,7 @@ namespace v8_extensions { CefRefPtr& retval, CefString& exception) { @autoreleasepool { - if (name == "exists") { - std::string cc_value = arguments[0]->GetStringValue().ToString(); - const char *path = cc_value.c_str(); - retval = CefV8Value::CreateBool(access(path, F_OK) == 0); - - return true; - } - else if (name == "read") { - NSString *path = stringFromCefV8Value(arguments[0]); - - NSError *error = nil; - NSStringEncoding *encoding = nil; - NSString *contents = [NSString stringWithContentsOfFile:path usedEncoding:encoding error:&error]; - - NSError *binaryFileError = nil; - if (error) { - contents = [NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:&binaryFileError]; - } - - if (binaryFileError) { - exception = [[binaryFileError localizedDescription] UTF8String]; - } - else { - retval = CefV8Value::CreateString([contents UTF8String]); - } - - return true; - } - else if (name == "write") { - NSString *path = stringFromCefV8Value(arguments[0]); - NSString *content = stringFromCefV8Value(arguments[1]); - - NSFileManager *fm = [NSFileManager defaultManager]; - - // Create parent directories if they don't exist - BOOL exists = [fm fileExistsAtPath:[path stringByDeletingLastPathComponent] isDirectory:nil]; - if (!exists) { - [fm createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; - } - - NSError *error = nil; - BOOL success = [content writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error]; - - if (error) { - exception = [[error localizedDescription] UTF8String]; - } - else if (!success) { - std::string exception = "Cannot write to '"; - exception += [path UTF8String]; - exception += "'"; - } - - return true; - } - else if (name == "absolute") { - NSString *path = stringFromCefV8Value(arguments[0]); - - path = [path stringByStandardizingPath]; - if ([path characterAtIndex:0] == '/') { - retval = CefV8Value::CreateString([path UTF8String]); - } - - return true; - } - else if (name == "getAllFilePathsAsync") { - std::string argument = arguments[0]->GetStringValue().ToString(); - CefRefPtr callback = arguments[1]; - CefRefPtr context = CefV8Context::GetCurrentContext(); - - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - dispatch_async(queue, ^{ - int rootPathLength = argument.size() + 1; - char rootPath[rootPathLength]; - strcpy(rootPath, argument.c_str()); - char * const treePaths[] = {rootPath, NULL}; - - FTS *tree = fts_open(treePaths, FTS_COMFOLLOW | FTS_PHYSICAL| FTS_NOCHDIR | FTS_NOSTAT, NULL); - std::vector paths; - - if (tree != NULL) { - FTSENT *entry; - int arrayIndex = 0; - while ((entry = fts_read(tree)) != NULL) { - if (entry->fts_level == 0) { - continue; - } - - bool isFile = entry->fts_info == FTS_NSOK; - if (!isFile) { - continue; - } - - int pathLength = entry->fts_pathlen - rootPathLength; - char relative[pathLength + 1]; - relative[pathLength] = '\0'; - strncpy(relative, entry->fts_path + rootPathLength, pathLength); - paths.push_back(relative); - } - } - - dispatch_queue_t mainQueue = dispatch_get_main_queue(); - dispatch_async(mainQueue, ^{ - context->Enter(); - CefRefPtr v8Paths = CefV8Value::CreateArray(paths.size()); - for (int i = 0; i < paths.size(); i++) { - v8Paths->SetValue(i, CefV8Value::CreateString(paths[i])); - } - CefV8ValueList callbackArgs; - callbackArgs.push_back(v8Paths); - callback->ExecuteFunction(callback, callbackArgs); - context->Exit(); - }); - }); - return true; - } - else if (name == "traverseTree") { - std::string argument = arguments[0]->GetStringValue().ToString(); - char rootPath[argument.size() + 1]; - strcpy(rootPath, argument.c_str()); - char * const paths[] = {rootPath, NULL}; - - FTS *tree = fts_open(paths, FTS_COMFOLLOW | FTS_PHYSICAL| FTS_NOCHDIR | FTS_NOSTAT, NULL); - if (tree == NULL) { - return true; - } - - CefRefPtr onFile = arguments[1]; - CefRefPtr onDir = arguments[2]; - CefV8ValueList args; - FTSENT *entry; - while ((entry = fts_read(tree)) != NULL) { - if (entry->fts_level == 0) { - continue; - } - - bool isFile = entry->fts_info == FTS_NSOK; - bool isDir = entry->fts_info == FTS_D; - if (!isFile && !isDir) { - continue; - } - - args.clear(); - args.push_back(CefV8Value::CreateString(entry->fts_path)); - if (isFile) { - onFile->ExecuteFunction(onFile, args); - } - else { - CefRefPtr enterDir = onDir->ExecuteFunction(onDir, args); - if(enterDir != NULL && !enterDir->GetBoolValue()) { - fts_set(tree, entry, FTS_SKIP); - } - } - } - - return true; - } - else if (name == "isDirectory") { - NSString *path = stringFromCefV8Value(arguments[0]); - - BOOL isDir = false; - BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; - retval = CefV8Value::CreateBool(exists && isDir); - - return true; - } - else if (name == "isFile") { - NSString *path = stringFromCefV8Value(arguments[0]); - - BOOL isDir = false; - BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; - retval = CefV8Value::CreateBool(exists && !isDir); - - return true; - } - else if (name == "remove") { - NSString *path = stringFromCefV8Value(arguments[0]); - - NSError *error = nil; - [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; - - if (error) { - exception = [[error localizedDescription] UTF8String]; - } - - return true; - } - else if (name == "writeToPasteboard") { + if (name == "writeToPasteboard") { NSString *text = stringFromCefV8Value(arguments[0]); NSPasteboard *pb = [NSPasteboard generalPasteboard]; @@ -268,8 +78,8 @@ namespace v8_extensions { CefV8ValueList args; - args.push_back(CefV8Value::CreateString(std::string([eventType UTF8String], [eventType lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); - args.push_back(CefV8Value::CreateString(std::string([path UTF8String], [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); + args.push_back(CefV8Value::CreateString(string([eventType UTF8String], [eventType lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); + args.push_back(CefV8Value::CreateString(string([path UTF8String], [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); function->ExecuteFunction(function, args); context->Exit(); @@ -281,7 +91,7 @@ namespace v8_extensions { retval = CefV8Value::CreateString([watchId UTF8String]); } else { - exception = std::string("Failed to watch path '") + std::string([path UTF8String]) + std::string("' (it may not exist)"); + exception = string("Failed to watch path '") + string([path UTF8String]) + string("' (it may not exist)"); } return true; @@ -318,32 +128,6 @@ namespace v8_extensions { [pathWatcher unwatchAllPaths]; return true; } - else if (name == "makeDirectory") { - NSString *path = stringFromCefV8Value(arguments[0]); - NSFileManager *fm = [NSFileManager defaultManager]; - NSError *error = nil; - [fm createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:&error]; - - if (error) { - exception = [[error localizedDescription] UTF8String]; - } - - return true; - } - else if (name == "move") { - NSString *sourcePath = stringFromCefV8Value(arguments[0]); - NSString *targetPath = stringFromCefV8Value(arguments[1]); - NSFileManager *fm = [NSFileManager defaultManager]; - - NSError *error = nil; - [fm moveItemAtPath:sourcePath toPath:targetPath error:&error]; - - if (error) { - exception = [[error localizedDescription] UTF8String]; - } - - return true; - } else if (name == "moveToTrash") { NSString *sourcePath = stringFromCefV8Value(arguments[0]); bool success = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation @@ -353,7 +137,7 @@ namespace v8_extensions { tag:nil]; if (!success) { - std::string exception = "Can not move "; + string exception = "Can not move "; exception += [sourcePath UTF8String]; exception += " to trash."; } @@ -363,146 +147,6 @@ namespace v8_extensions { else if (name == "reload") { CefV8Context::GetCurrentContext()->GetBrowser()->ReloadIgnoreCache(); } - else if (name == "lastModified") { - NSString *path = stringFromCefV8Value(arguments[0]); - NSFileManager *fm = [NSFileManager defaultManager]; - - NSError *error = nil; - NSDictionary *attributes = [fm attributesOfItemAtPath:path error:&error]; - - if (error) { - exception = [[error localizedDescription] UTF8String]; - } - - NSDate *lastModified = [attributes objectForKey:NSFileModificationDate]; - retval = CefV8Value::CreateDate(CefTime([lastModified timeIntervalSince1970])); - return true; - } - else if (name == "md5ForPath") { - NSString *path = stringFromCefV8Value(arguments[0]); - unsigned char outputData[CC_MD5_DIGEST_LENGTH]; - - NSData *inputData = [[NSData alloc] initWithContentsOfFile:path]; - CC_MD5([inputData bytes], [inputData length], outputData); - [inputData release]; - - NSMutableString *hash = [[NSMutableString alloc] init]; - - for (NSUInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { - [hash appendFormat:@"%02x", outputData[i]]; - } - - retval = CefV8Value::CreateString([hash UTF8String]); - return true; - } - else if (name == "exec") { - NSString *command = stringFromCefV8Value(arguments[0]); - CefRefPtr options = arguments[1]; - CefRefPtr callback = arguments[2]; - - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath:@"/bin/sh"]; - [task setStandardInput:[NSFileHandle fileHandleWithNullDevice]]; - [task setArguments:[NSArray arrayWithObjects:@"-l", @"-c", command, nil]]; - - NSPipe *stdout = [NSPipe pipe]; - NSPipe *stderr = [NSPipe pipe]; - [task setStandardOutput:stdout]; - [task setStandardError:stderr]; - - CefRefPtr context = CefV8Context::GetCurrentContext(); - void (^outputHandle)(NSString *contents, CefRefPtr function) = nil; - void (^taskTerminatedHandle)(NSString *output, NSString *errorOutput) = nil; - - outputHandle = ^(NSString *contents, CefRefPtr function) { - context->Enter(); - - CefV8ValueList args; - args.push_back(CefV8Value::CreateString(std::string([contents UTF8String], [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); - CefRefPtr retval = function->ExecuteFunction(function, args); - - if (function->HasException()) { - throwException(context->GetGlobal(), function->GetException(), @"Error thrown in OutputHandle"); - } - - context->Exit(); - }; - - taskTerminatedHandle = ^(NSString *output, NSString *errorOutput) { - context->Enter(); - - CefV8ValueList args; - args.push_back(CefV8Value::CreateInt([task terminationStatus])); - args.push_back(CefV8Value::CreateString([output UTF8String])); - args.push_back(CefV8Value::CreateString([errorOutput UTF8String])); - - callback->ExecuteFunction(callback, args); - - if (callback->HasException()) { - throwException(context->GetGlobal(), callback->GetException(), @"Error thrown in TaskTerminatedHandle"); - } - - context->Exit(); - - stdout.fileHandleForReading.readabilityHandler = nil; - stderr.fileHandleForReading.readabilityHandler = nil; - }; - - task.terminationHandler = ^(NSTask *) { - @synchronized(task) { - NSData *outputData = [[stdout fileHandleForReading] readDataToEndOfFile]; - NSString *output = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; - NSData *errorData = [[stderr fileHandleForReading] readDataToEndOfFile]; - NSString *errorOutput = [[NSString alloc] initWithData:errorData encoding:NSUTF8StringEncoding]; - dispatch_sync(dispatch_get_main_queue(), ^() { - taskTerminatedHandle(output, errorOutput); - }); - [output release]; - [errorOutput release]; - } - }; - - CefRefPtr stdoutFunction = options->GetValue("stdout"); - if (stdoutFunction->IsFunction()) { - stdout.fileHandleForReading.readabilityHandler = ^(NSFileHandle *fileHandle) { - @synchronized(task) { - NSData *data = [fileHandle availableData]; - NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - dispatch_sync(dispatch_get_main_queue(), ^() { - outputHandle(contents, stdoutFunction); - }); - [contents release]; - } - }; - } - - CefRefPtr stderrFunction = options->GetValue("stderr"); - if (stderrFunction->IsFunction()) { - stderr.fileHandleForReading.readabilityHandler = ^(NSFileHandle *fileHandle) { - @synchronized(task) { - NSData *data = [fileHandle availableData]; - NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - dispatch_sync(dispatch_get_main_queue(), ^() { - outputHandle(contents, stderrFunction); - }); - [contents release]; - } - }; - } - - CefRefPtr currentWorkingDirectory = options->GetValue("cwd"); - if (!currentWorkingDirectory->IsUndefined() && !currentWorkingDirectory->IsNull()) { - [task setCurrentDirectoryPath:stringFromCefV8Value(currentWorkingDirectory)]; - } - - [task launch]; - - return true; - } - else if (name == "getPlatform") { - retval = CefV8Value::CreateString("mac"); - return true; - } else if (name == "setWindowState") { [windowStateLock lock]; @@ -518,32 +162,8 @@ namespace v8_extensions { return true; } - else if (name == "isMisspelled") { - NSString *word = stringFromCefV8Value(arguments[0]); - NSSpellChecker *spellChecker = [NSSpellChecker sharedSpellChecker]; - @synchronized(spellChecker) { - NSRange range = [spellChecker checkSpellingOfString:word startingAt:0]; - retval = CefV8Value::CreateBool(range.length > 0); - } - return true; - } - - else if (name == "getCorrectionsForMisspelling") { - NSString *misspelling = stringFromCefV8Value(arguments[0]); - NSSpellChecker *spellChecker = [NSSpellChecker sharedSpellChecker]; - @synchronized(spellChecker) { - NSString *language = [spellChecker language]; - NSRange range; - range.location = 0; - range.length = [misspelling length]; - NSArray *guesses = [spellChecker guessesForWordRange:range inString:misspelling language:language inSpellDocumentWithTag:0]; - CefRefPtr v8Guesses = CefV8Value::CreateArray([guesses count]); - for (int i = 0; i < [guesses count]; i++) { - v8Guesses->SetValue(i, CefV8Value::CreateString([[guesses objectAtIndex:i] UTF8String])); - } - retval = v8Guesses; - } - return true; + else if (name == "beep") { + NSBeep(); } return false; @@ -551,7 +171,7 @@ namespace v8_extensions { }; NSString *stringFromCefV8Value(const CefRefPtr& value) { - std::string cc_value = value->GetStringValue().ToString(); + string cc_value = value->GetStringValue().ToString(); return [NSString stringWithUTF8String:cc_value.c_str()]; } @@ -559,7 +179,7 @@ namespace v8_extensions { CefV8ValueList arguments; message = [message stringByAppendingFormat:@"\n%s", exception->GetMessage().ToString().c_str()]; - arguments.push_back(CefV8Value::CreateString(std::string([message UTF8String], [message lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); + arguments.push_back(CefV8Value::CreateString(string([message UTF8String], [message lengthOfBytesUsingEncoding:NSUTF8StringEncoding]))); CefRefPtr console = global->GetValue("console"); console->GetValue("error")->ExecuteFunction(console, arguments); diff --git a/native/v8_extensions/native_linux.cpp b/native/v8_extensions/native_linux.cpp index b70917226..2f309b5cd 100644 --- a/native/v8_extensions/native_linux.cpp +++ b/native/v8_extensions/native_linux.cpp @@ -515,8 +515,6 @@ bool NativeHandler::Execute(const CefString& name, CefRefPtr object, UnwatchPath(name, object, arguments, retval, exception); else if (name == "md5ForPath") Digest(name, object, arguments, retval, exception); - else if (name == "getPlatform") - retval = CefV8Value::CreateString("linux"); else if (name == "lastModified") LastModified(name, object, arguments, retval, exception); else diff --git a/native/v8_extensions/onig_reg_exp.h b/native/v8_extensions/onig_reg_exp.h deleted file mode 100644 index 4db0d0e32..000000000 --- a/native/v8_extensions/onig_reg_exp.h +++ /dev/null @@ -1,24 +0,0 @@ -#include "include/cef_base.h" -#include "include/cef_v8.h" - -namespace v8_extensions { - - class OnigRegExp : public CefV8Handler { - public: - OnigRegExp(); - void CreateContextBinding(CefRefPtr context); - virtual bool Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) OVERRIDE; - - // Provide the reference counting implementation for this class. - IMPLEMENT_REFCOUNTING(OnigRegExp); - - private: - OnigRegExp(OnigRegExp const&); - void operator=(OnigRegExp const&); - }; - -} \ No newline at end of file diff --git a/native/v8_extensions/onig_reg_exp.mm b/native/v8_extensions/onig_reg_exp.mm deleted file mode 100644 index 21b59b342..000000000 --- a/native/v8_extensions/onig_reg_exp.mm +++ /dev/null @@ -1,106 +0,0 @@ -#import -#import -#import "CocoaOniguruma/OnigRegexp.h" -#import "include/cef_base.h" -#import "include/cef_v8.h" -#import "onig_reg_exp.h" - -namespace v8_extensions { - -extern NSString *stringFromCefV8Value(const CefRefPtr& value); - -class OnigRegExpUserData : public CefBase { -public: - OnigRegExpUserData(CefRefPtr source) { - NSString *sourceString = [NSString stringWithUTF8String:source->GetStringValue().ToString().c_str()]; - m_regex = [[OnigRegexp compile:sourceString] retain]; - } - - ~OnigRegExpUserData() { - [m_regex release]; - } - - CefRefPtr Search(CefRefPtr string, CefRefPtr index) { - OnigResult *result = [m_regex search:stringFromCefV8Value(string) start:index->GetIntValue()]; - - if ([result count] == 0) return CefV8Value::CreateNull(); - - CefRefPtr resultArray = CefV8Value::CreateArray(result.count); - CefRefPtr indicesArray = CefV8Value::CreateArray(result.count); - - for (int i = 0; i < [result count]; i++) { - resultArray->SetValue(i, CefV8Value::CreateString([[result stringAt:i] UTF8String])); - indicesArray->SetValue(i, CefV8Value::CreateInt([result locationAt:i])); - } - - resultArray->SetValue("index", CefV8Value::CreateInt([result locationAt:0]), V8_PROPERTY_ATTRIBUTE_NONE); - resultArray->SetValue("indices", indicesArray, V8_PROPERTY_ATTRIBUTE_NONE); - - return resultArray; - } - - CefRefPtr Test(CefRefPtr string, CefRefPtr index) { - OnigResult *result = [m_regex search:stringFromCefV8Value(string) start:index->GetIntValue()]; - return CefV8Value::CreateBool(result); - } - - OnigRegexp *m_regex; - - IMPLEMENT_REFCOUNTING(OnigRegexpUserData); -}; - -OnigRegExp::OnigRegExp() : CefV8Handler() { -} - -void OnigRegExp::CreateContextBinding(CefRefPtr context) { - const char* methodNames[] = { "search", "test", "buildOnigRegExp" }; - - CefRefPtr nativeObject = CefV8Value::CreateObject(NULL); - int arrayLength = sizeof(methodNames) / sizeof(const char *); - for (int i = 0; i < arrayLength; i++) { - const char *functionName = methodNames[i]; - CefRefPtr function = CefV8Value::CreateFunction(functionName, this); - nativeObject->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE); - } - - CefRefPtr global = context->GetGlobal(); - global->SetValue("$onigRegExp", nativeObject, V8_PROPERTY_ATTRIBUTE_NONE); -} - -bool OnigRegExp::Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) { - - @autoreleasepool { - if (name == "search") { - CefRefPtr string = arguments[0]; - CefRefPtr index = arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0); - OnigRegExpUserData *userData = (OnigRegExpUserData *)object->GetUserData().get(); - retval = userData->Search(string, index); - return true; - } - else if (name == "test") { - CefRefPtr string = arguments[0]; - CefRefPtr index = arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0); - OnigRegExpUserData *userData = (OnigRegExpUserData *)object->GetUserData().get(); - retval = userData->Test(string, index); - return true; - } - else if (name == "buildOnigRegExp") { - CefRefPtr pattern = arguments[0]; - CefRefPtr userData = new OnigRegExpUserData(pattern); - if (!userData->m_regex) { - exception = std::string("Failed to create OnigRegExp from pattern '") + pattern->GetStringValue().ToString() + "'"; - } - retval = CefV8Value::CreateObject(NULL); - retval->SetUserData((CefRefPtr)userData); - return true; - } - - return false; - } -} - -} // namespace v8_extensions \ No newline at end of file diff --git a/native/v8_extensions/onig_reg_exp_linux.cpp b/native/v8_extensions/onig_reg_exp_linux.cpp deleted file mode 100644 index 82f1db910..000000000 --- a/native/v8_extensions/onig_reg_exp_linux.cpp +++ /dev/null @@ -1,228 +0,0 @@ -#include "onig_reg_exp.h" -#include "include/cef_runnable.h" -#include -#include -#include -#include "io_utils.h" - -using namespace std; - -namespace v8_extensions { - -class OnigRegexpUserData: public CefBase { -public: - OnigRegexpUserData(CefRefPtr source) { - OnigErrorInfo error; - string input = source->GetStringValue().ToString(); - int length = input.length(); - UChar* pattern = (UChar*) input.c_str(); - int code = onig_new(®ex, pattern, pattern + length, - ONIG_OPTION_SINGLELINE, ONIG_ENCODING_UTF8, ONIG_SYNTAX_DEFAULT, - &error); - if (code != ONIG_NORMAL) { - char errorText[ONIG_MAX_ERROR_MESSAGE_LEN]; - onig_error_code_to_str((OnigUChar*) errorText, code, &error); - cout << errorText << " for pattern: " << input << endl; - } - } - - ~OnigRegexpUserData() { - onig_free(regex); - } - - OnigRegion* SearchRegion(string input, int index) { - if (!regex) - return NULL; - - OnigRegion* region = onig_region_new(); - UChar* search = (UChar*) input.c_str(); - unsigned char* start = search + index; - unsigned char* end = search + input.length(); - int code = onig_search(regex, search, end, start, end, region, - ONIG_OPTION_NONE); - if (code >= 0) - return region; - else { - onig_region_free(region, 1); - return NULL; - } - } - - CefRefPtr Search(CefRefPtr argument, - CefRefPtr index) { - string input = argument->GetStringValue().ToString(); - OnigRegion* region = SearchRegion(input, index->GetIntValue()); - if (!region) - return CefV8Value::CreateNull(); - - CefRefPtr indices; - CefRefPtr resultArray = CefV8Value::CreateArray( - region->num_regs); - CefRefPtr indicesArray = CefV8Value::CreateArray( - region->num_regs); - for (int i = 0; i < region->num_regs; i++) { - int begin = region->beg[i]; - int end = region->end[i]; - resultArray->SetValue(i, - CefV8Value::CreateString(input.substr(begin, end - begin))); - indicesArray->SetValue(i, CefV8Value::CreateInt(begin)); - } - resultArray->SetValue("index", CefV8Value::CreateInt(region->beg[0]), - V8_PROPERTY_ATTRIBUTE_NONE); - resultArray->SetValue("indices", indicesArray, V8_PROPERTY_ATTRIBUTE_NONE); - onig_region_free(region, 1); - return resultArray; - } - - CefRefPtr Test(CefRefPtr argument, - CefRefPtr index) { - OnigRegion* region = SearchRegion(argument->GetStringValue().ToString(), - index->GetIntValue()); - CefRefPtr text = CefV8Value::CreateBool(region != NULL); - if (region) - onig_region_free(region, 1); - return text; - } - - CefRefPtr GetCaptureIndices(CefRefPtr argument, - CefRefPtr index) { - OnigRegion* region = SearchRegion(argument->GetStringValue().ToString(), - index->GetIntValue()); - CefRefPtr indices; - if (region) { - indices = BuildCaptureIndices(region); - onig_region_free(region, 1); - } else - indices = CefV8Value::CreateNull(); - return indices; - } - - CefRefPtr BuildCaptureIndices(OnigRegion *region) { - CefRefPtr array = CefV8Value::CreateArray(region->num_regs * 3); - int i = 0; - for (int index = 0; index < region->num_regs; index++) { - int begin = region->beg[index]; - int end = region->end[index]; - if (end - begin <= 0) - continue; - array->SetValue(i++, CefV8Value::CreateInt(index)); - array->SetValue(i++, CefV8Value::CreateInt(begin)); - array->SetValue(i++, CefV8Value::CreateInt(end)); - } - - return array; - } - - CefRefPtr CaptureCount() { - if (regex) - return CefV8Value::CreateInt(onig_number_of_captures(regex)); - else - return CefV8Value::CreateInt(0); - } - - regex_t* regex; - -IMPLEMENT_REFCOUNTING(OnigRegexpUserData) - ; -} -; - -OnigRegExp::OnigRegExp() : - CefV8Handler() { - string realFilePath = io_utils_real_app_path( - "/native/v8_extensions/onig_reg_exp.js"); - if (!realFilePath.empty()) { - string extensionCode; - if (io_utils_read(realFilePath, &extensionCode) > 0) - CefRegisterExtension("v8/onig-reg-exp", extensionCode, this); - } -} - -bool OnigRegExp::Execute(const CefString& name, - CefRefPtr object, const CefV8ValueList& arguments, - CefRefPtr& retval, CefString& exception) { - if (name == "captureIndices") { - CefRefPtr string = arguments[0]; - CefRefPtr index = arguments[1]; - CefRefPtr regexes = arguments[2]; - - int bestIndex = -1; - CefRefPtr captureIndicesForBestIndex; - CefRefPtr captureIndices; - - retval = CefV8Value::CreateObject(NULL); - for (int i = 0; i < regexes->GetArrayLength(); i++) { - OnigRegexpUserData *userData = - (OnigRegexpUserData *) regexes->GetValue(i)->GetUserData().get(); - captureIndices = userData->GetCaptureIndices(string, index); - if (captureIndices->IsNull()) - continue; - - if (bestIndex == -1 - || captureIndices->GetValue(1)->GetIntValue() - < captureIndicesForBestIndex->GetValue(1)->GetIntValue()) { - bestIndex = i; - captureIndicesForBestIndex = captureIndices; - if (captureIndices->GetValue(1)->GetIntValue() == 0) - break; // If the match starts at 0, just use it! - } - } - - if (bestIndex != -1) { - retval->SetValue("index", CefV8Value::CreateInt(bestIndex), - V8_PROPERTY_ATTRIBUTE_NONE); - retval->SetValue("captureIndices", captureIndicesForBestIndex, - V8_PROPERTY_ATTRIBUTE_NONE); - } - - return true; - - } - - if (name == "getCaptureIndices") { - CefRefPtr string = arguments[0]; - CefRefPtr index = - arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0); - OnigRegexpUserData *userData = - (OnigRegexpUserData *) object->GetUserData().get(); - retval = userData->GetCaptureIndices(string, index); - return true; - } - - if (name == "search") { - CefRefPtr string = arguments[0]; - CefRefPtr index = - arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0); - OnigRegexpUserData *userData = - (OnigRegexpUserData *) object->GetUserData().get(); - retval = userData->Search(string, index); - return true; - } - - if (name == "test") { - CefRefPtr string = arguments[0]; - CefRefPtr index = - arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0); - OnigRegexpUserData *userData = - (OnigRegexpUserData *) object->GetUserData().get(); - retval = userData->Test(string, index); - return true; - } - - if (name == "buildOnigRegExp") { - CefRefPtr userData = new OnigRegexpUserData(arguments[0]); - retval = CefV8Value::CreateObject(NULL); - retval->SetUserData(userData); - return true; - } - - if (name == "getCaptureCount") { - OnigRegexpUserData *userData = - (OnigRegexpUserData *) object->GetUserData().get(); - retval = userData->CaptureCount(); - return true; - } - - return false; -} -} diff --git a/native/v8_extensions/onig_scanner.h b/native/v8_extensions/onig_scanner.h deleted file mode 100644 index 33a2bb1af..000000000 --- a/native/v8_extensions/onig_scanner.h +++ /dev/null @@ -1,24 +0,0 @@ -#include "include/cef_base.h" -#include "include/cef_v8.h" - -namespace v8_extensions { - - class OnigScanner : public CefV8Handler { - public: - OnigScanner(); - void CreateContextBinding(CefRefPtr context); - virtual bool Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) OVERRIDE; - - // Provide the reference counting implementation for this class. - IMPLEMENT_REFCOUNTING(OnigRegExp); - - private: - OnigScanner(OnigScanner const&); - void operator=(OnigScanner const&); - }; - -} \ No newline at end of file diff --git a/native/v8_extensions/onig_scanner.mm b/native/v8_extensions/onig_scanner.mm deleted file mode 100644 index 3a8db417f..000000000 --- a/native/v8_extensions/onig_scanner.mm +++ /dev/null @@ -1,171 +0,0 @@ -#import -#import -#import "CocoaOniguruma/OnigRegexp.h" -#import "include/cef_base.h" -#import "include/cef_v8.h" -#import "onig_scanner.h" - -namespace v8_extensions { - -using namespace std; -extern NSString *stringFromCefV8Value(const CefRefPtr& value); - -class OnigScannerUserData : public CefBase { - public: - OnigScannerUserData(CefRefPtr sources) { - int length = sources->GetArrayLength(); - - regExps.resize(length); - cachedResults.resize(length); - - for (int i = 0; i < length; i++) { - NSString *sourceString = stringFromCefV8Value(sources->GetValue(i)); - regExps[i] = [[OnigRegexp compile:sourceString] retain]; - } - } - - ~OnigScannerUserData() { - for (vector::iterator iter = regExps.begin(); iter < regExps.end(); iter++) { - [*iter release]; - } - for (vector::iterator iter = cachedResults.begin(); iter < cachedResults.end(); iter++) { - [*iter release]; - } - } - - CefRefPtr FindNextMatch(CefRefPtr v8String, CefRefPtr v8StartLocation) { - - std::string string = v8String->GetStringValue().ToString(); - int startLocation = v8StartLocation->GetIntValue(); - int bestIndex = -1; - int bestLocation = NULL; - OnigResult *bestResult = NULL; - - bool useCachedResults = (string == lastMatchedString && startLocation >= lastStartLocation); - lastStartLocation = startLocation; - - if (!useCachedResults) { - ClearCachedResults(); - lastMatchedString = string; - } - - vector::iterator iter = regExps.begin(); - int index = 0; - while (iter < regExps.end()) { - OnigRegexp *regExp = *iter; - - bool useCachedResult = false; - OnigResult *result = NULL; - - if (useCachedResults && index <= maxCachedIndex) { - result = cachedResults[index]; - useCachedResult = (result == NULL || [result locationAt:0] >= startLocation); - } - - if (!useCachedResult) { - result = [regExp search:[NSString stringWithUTF8String:string.c_str()] start:startLocation]; - cachedResults[index] = [result retain]; - maxCachedIndex = index; - } - - if ([result count] > 0) { - int location = [result locationAt:0]; - if (bestIndex == -1 || location < bestLocation) { - bestLocation = location; - bestResult = result; - bestIndex = index; - } - - if (location == startLocation) { - break; - } - } - - iter++; - index++; - } - - if (bestIndex >= 0) { - CefRefPtr result = CefV8Value::CreateObject(NULL); - result->SetValue("index", CefV8Value::CreateInt(bestIndex), V8_PROPERTY_ATTRIBUTE_NONE); - result->SetValue("captureIndices", CaptureIndicesForMatch(bestResult), V8_PROPERTY_ATTRIBUTE_NONE); - return result; - } else { - return CefV8Value::CreateNull(); - } - } - - void ClearCachedResults() { - maxCachedIndex = -1; - for (vector::iterator iter = cachedResults.begin(); iter < cachedResults.end(); iter++) { - [*iter release]; - *iter = NULL; - } - } - - CefRefPtr CaptureIndicesForMatch(OnigResult *result) { - CefRefPtr array = CefV8Value::CreateArray([result count] * 3); - int i = 0; - int resultCount = [result count]; - for (int index = 0; index < resultCount; index++) { - int captureLength = [result lengthAt:index]; - int captureStart = [result locationAt:index]; - - array->SetValue(i++, CefV8Value::CreateInt(index)); - array->SetValue(i++, CefV8Value::CreateInt(captureStart)); - array->SetValue(i++, CefV8Value::CreateInt(captureStart + captureLength)); - } - - return array; - } - - protected: - std::vector regExps; - std::string lastMatchedString; - std::vector cachedResults; - int maxCachedIndex; - int lastStartLocation; - - IMPLEMENT_REFCOUNTING(OnigRegexpUserData); -}; - -OnigScanner::OnigScanner() : CefV8Handler() { -} - -void OnigScanner::CreateContextBinding(CefRefPtr context) { - const char* methodNames[] = { "findNextMatch", "buildScanner" }; - - CefRefPtr nativeObject = CefV8Value::CreateObject(NULL); - int arrayLength = sizeof(methodNames) / sizeof(const char *); - for (int i = 0; i < arrayLength; i++) { - const char *functionName = methodNames[i]; - CefRefPtr function = CefV8Value::CreateFunction(functionName, this); - nativeObject->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE); - } - - CefRefPtr global = context->GetGlobal(); - global->SetValue("$onigScanner", nativeObject, V8_PROPERTY_ATTRIBUTE_NONE); -} - -bool OnigScanner::Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) { - @autoreleasepool { - if (name == "findNextMatch") { - OnigScannerUserData *userData = (OnigScannerUserData *)object->GetUserData().get(); - retval = userData->FindNextMatch(arguments[0], arguments[1]); - return true; - } - else if (name == "buildScanner") { - retval = CefV8Value::CreateObject(NULL); - retval->SetUserData(new OnigScannerUserData(arguments[0])); - return true; - } - - return false; - } -} - -} // namespace v8_extensions diff --git a/native/v8_extensions/readtags.c b/native/v8_extensions/readtags.c deleted file mode 100644 index 4cab3f358..000000000 --- a/native/v8_extensions/readtags.c +++ /dev/null @@ -1,970 +0,0 @@ -/* -* $Id: readtags.c 592 2007-07-31 03:30:41Z dhiebert $ -* -* Copyright (c) 1996-2003, Darren Hiebert -* -* This source code is released into the public domain. -* -* This module contains functions for reading tag files. -*/ - -/* -* INCLUDE FILES -*/ -#include -#include -#include -#include -#include -#include /* to declare off_t */ - -#include "readtags.h" - -/* -* MACROS -*/ -#define TAB '\t' - - -/* -* DATA DECLARATIONS -*/ -typedef struct { - size_t size; - char *buffer; -} vstring; - -/* Information about current tag file */ -struct sTagFile { - /* has the file been opened and this structure initialized? */ - short initialized; - /* format of tag file */ - short format; - /* how is the tag file sorted? */ - sortType sortMethod; - /* pointer to file structure */ - FILE* fp; - /* file position of first character of `line' */ - off_t pos; - /* size of tag file in seekable positions */ - off_t size; - /* last line read */ - vstring line; - /* name of tag in last line read */ - vstring name; - /* defines tag search state */ - struct { - /* file position of last match for tag */ - off_t pos; - /* name of tag last searched for */ - char *name; - /* length of name for partial matches */ - size_t nameLength; - /* peforming partial match */ - short partial; - /* ignoring case */ - short ignorecase; - } search; - /* miscellaneous extension fields */ - struct { - /* number of entries in `list' */ - unsigned short max; - /* list of key value pairs */ - tagExtensionField *list; - } fields; - /* buffers to be freed at close */ - struct { - /* name of program author */ - char *author; - /* name of program */ - char *name; - /* URL of distribution */ - char *url; - /* program version */ - char *version; - } program; -}; - -/* -* DATA DEFINITIONS -*/ -const char *const EmptyString = ""; -const char *const PseudoTagPrefix = "!_"; - -/* -* FUNCTION DEFINITIONS -*/ - -/* - * Compare two strings, ignoring case. - * Return 0 for match, < 0 for smaller, > 0 for bigger - * Make sure case is folded to uppercase in comparison (like for 'sort -f') - * This makes a difference when one of the chars lies between upper and lower - * ie. one of the chars [ \ ] ^ _ ` for ascii. (The '_' in particular !) - */ -static int struppercmp (const char *s1, const char *s2) -{ - int result; - do - { - result = toupper ((int) *s1) - toupper ((int) *s2); - } while (result == 0 && *s1++ != '\0' && *s2++ != '\0'); - return result; -} - -static int strnuppercmp (const char *s1, const char *s2, size_t n) -{ - int result; - do - { - result = toupper ((int) *s1) - toupper ((int) *s2); - } while (result == 0 && --n > 0 && *s1++ != '\0' && *s2++ != '\0'); - return result; -} - -static int growString (vstring *s) -{ - int result = 0; - size_t newLength; - char *newLine; - if (s->size == 0) - { - newLength = 128; - newLine = (char*) malloc (newLength); - *newLine = '\0'; - } - else - { - newLength = 2 * s->size; - newLine = (char*) realloc (s->buffer, newLength); - } - if (newLine == NULL) - perror ("string too large"); - else - { - s->buffer = newLine; - s->size = newLength; - result = 1; - } - return result; -} - -/* Copy name of tag out of tag line */ -static void copyName (tagFile *const file) -{ - size_t length; - const char *end = strchr (file->line.buffer, '\t'); - if (end == NULL) - { - end = strchr (file->line.buffer, '\n'); - if (end == NULL) - end = strchr (file->line.buffer, '\r'); - } - if (end != NULL) - length = end - file->line.buffer; - else - length = strlen (file->line.buffer); - while (length >= file->name.size) - growString (&file->name); - strncpy (file->name.buffer, file->line.buffer, length); - file->name.buffer [length] = '\0'; -} - -static int readTagLineRaw (tagFile *const file) -{ - int result = 1; - int reReadLine; - - /* If reading the line places any character other than a null or a - * newline at the last character position in the buffer (one less than - * the buffer size), then we must resize the buffer and reattempt to read - * the line. - */ - do - { - char *const pLastChar = file->line.buffer + file->line.size - 2; - char *line; - - file->pos = ftell (file->fp); - reReadLine = 0; - *pLastChar = '\0'; - line = fgets (file->line.buffer, (int) file->line.size, file->fp); - if (line == NULL) - { - /* read error */ - if (! feof (file->fp)) - perror ("readTagLine"); - result = 0; - } - else if (*pLastChar != '\0' && - *pLastChar != '\n' && *pLastChar != '\r') - { - /* buffer overflow */ - growString (&file->line); - fseek (file->fp, file->pos, SEEK_SET); - reReadLine = 1; - } - else - { - size_t i = strlen (file->line.buffer); - while (i > 0 && - (file->line.buffer [i - 1] == '\n' || file->line.buffer [i - 1] == '\r')) - { - file->line.buffer [i - 1] = '\0'; - --i; - } - } - } while (reReadLine && result); - if (result) - copyName (file); - return result; -} - -static int readTagLine (tagFile *const file) -{ - int result; - do - { - result = readTagLineRaw (file); - } while (result && *file->name.buffer == '\0'); - return result; -} - -static tagResult growFields (tagFile *const file) -{ - tagResult result = TagFailure; - unsigned short newCount = (unsigned short) 2 * file->fields.max; - tagExtensionField *newFields = (tagExtensionField*) - realloc (file->fields.list, newCount * sizeof (tagExtensionField)); - if (newFields == NULL) - perror ("too many extension fields"); - else - { - file->fields.list = newFields; - file->fields.max = newCount; - result = TagSuccess; - } - return result; -} - -static void parseExtensionFields (tagFile *const file, tagEntry *const entry, - char *const string) -{ - char *p = string; - while (p != NULL && *p != '\0') - { - while (*p == TAB) - *p++ = '\0'; - if (*p != '\0') - { - char *colon; - char *field = p; - p = strchr (p, TAB); - if (p != NULL) - *p++ = '\0'; - colon = strchr (field, ':'); - if (colon == NULL) - entry->kind = field; - else - { - const char *key = field; - const char *value = colon + 1; - *colon = '\0'; - if (strcmp (key, "kind") == 0) - entry->kind = value; - else if (strcmp (key, "file") == 0) - entry->fileScope = 1; - else if (strcmp (key, "line") == 0) - entry->address.lineNumber = atol (value); - else - { - if (entry->fields.count == file->fields.max) - growFields (file); - file->fields.list [entry->fields.count].key = key; - file->fields.list [entry->fields.count].value = value; - ++entry->fields.count; - } - } - } - } -} - -static void parseTagLine (tagFile *file, tagEntry *const entry) -{ - int i; - char *p = file->line.buffer; - char *tab = strchr (p, TAB); - - entry->fields.list = NULL; - entry->fields.count = 0; - entry->kind = NULL; - entry->fileScope = 0; - - entry->name = p; - if (tab != NULL) - { - *tab = '\0'; - p = tab + 1; - entry->file = p; - tab = strchr (p, TAB); - if (tab != NULL) - { - int fieldsPresent; - *tab = '\0'; - p = tab + 1; - if (*p == '/' || *p == '?') - { - /* parse pattern */ - int delimiter = *(unsigned char*) p; - entry->address.lineNumber = 0; - entry->address.pattern = p; - do - { - p = strchr (p + 1, delimiter); - if (p == NULL) - break; - if (*(p - 1) != '\\') - break; - // Make sure preceding backslash isn't an escaped backslash by - // advancing backwards and counting the number of backslashes - int slashCount = 1; - while (*(p - slashCount - 1) == '\\') - slashCount++; - if (slashCount % 2 == 0) - break; - } while (1); - if (p == NULL) - { - /* invalid pattern */ - } - else - ++p; - } - else if (isdigit ((int) *(unsigned char*) p)) - { - /* parse line number */ - entry->address.pattern = p; - entry->address.lineNumber = atol (p); - while (isdigit ((int) *(unsigned char*) p)) - ++p; - } - else - { - /* invalid pattern */ - } - fieldsPresent = (strncmp (p, ";\"", 2) == 0); - *p = '\0'; - if (fieldsPresent) - parseExtensionFields (file, entry, p + 2); - } - } - if (entry->fields.count > 0) - entry->fields.list = file->fields.list; - for (i = entry->fields.count ; i < file->fields.max ; ++i) - { - file->fields.list [i].key = NULL; - file->fields.list [i].value = NULL; - } -} - -static char *duplicate (const char *str) -{ - char *result = NULL; - if (str != NULL) - { - result = strdup (str); - if (result == NULL) - perror (NULL); - } - return result; -} - -static void readPseudoTags (tagFile *const file, tagFileInfo *const info) -{ - fpos_t startOfLine; - const size_t prefixLength = strlen (PseudoTagPrefix); - if (info != NULL) - { - info->file.format = 1; - info->file.sort = TAG_UNSORTED; - info->program.author = NULL; - info->program.name = NULL; - info->program.url = NULL; - info->program.version = NULL; - } - while (1) - { - fgetpos (file->fp, &startOfLine); - if (! readTagLine (file)) - break; - if (strncmp (file->line.buffer, PseudoTagPrefix, prefixLength) != 0) - break; - else - { - tagEntry entry; - const char *key, *value; - parseTagLine (file, &entry); - key = entry.name + prefixLength; - value = entry.file; - if (strcmp (key, "TAG_FILE_SORTED") == 0) - file->sortMethod = (sortType) atoi (value); - else if (strcmp (key, "TAG_FILE_FORMAT") == 0) - file->format = (short) atoi (value); - else if (strcmp (key, "TAG_PROGRAM_AUTHOR") == 0) - file->program.author = duplicate (value); - else if (strcmp (key, "TAG_PROGRAM_NAME") == 0) - file->program.name = duplicate (value); - else if (strcmp (key, "TAG_PROGRAM_URL") == 0) - file->program.url = duplicate (value); - else if (strcmp (key, "TAG_PROGRAM_VERSION") == 0) - file->program.version = duplicate (value); - if (info != NULL) - { - info->file.format = file->format; - info->file.sort = file->sortMethod; - info->program.author = file->program.author; - info->program.name = file->program.name; - info->program.url = file->program.url; - info->program.version = file->program.version; - } - } - } - fsetpos (file->fp, &startOfLine); -} - -static void gotoFirstLogicalTag (tagFile *const file) -{ - fpos_t startOfLine; - const size_t prefixLength = strlen (PseudoTagPrefix); - rewind (file->fp); - while (1) - { - fgetpos (file->fp, &startOfLine); - if (! readTagLine (file)) - break; - if (strncmp (file->line.buffer, PseudoTagPrefix, prefixLength) != 0) - break; - } - fsetpos (file->fp, &startOfLine); -} - -static tagFile *initialize (const char *const filePath, tagFileInfo *const info) -{ - tagFile *result = (tagFile*) calloc ((size_t) 1, sizeof (tagFile)); - if (result != NULL) - { - growString (&result->line); - growString (&result->name); - result->fields.max = 20; - result->fields.list = (tagExtensionField*) calloc ( - result->fields.max, sizeof (tagExtensionField)); - result->fp = fopen (filePath, "r"); - if (result->fp == NULL) - { - free (result); - result = NULL; - info->status.error_number = errno; - } - else - { - fseek (result->fp, 0, SEEK_END); - result->size = ftell (result->fp); - rewind (result->fp); - readPseudoTags (result, info); - info->status.opened = 1; - result->initialized = 1; - } - } - return result; -} - -static void terminate (tagFile *const file) -{ - fclose (file->fp); - - free (file->line.buffer); - free (file->name.buffer); - free (file->fields.list); - - if (file->program.author != NULL) - free (file->program.author); - if (file->program.name != NULL) - free (file->program.name); - if (file->program.url != NULL) - free (file->program.url); - if (file->program.version != NULL) - free (file->program.version); - if (file->search.name != NULL) - free (file->search.name); - - memset (file, 0, sizeof (tagFile)); - - free (file); -} - -static tagResult readNext (tagFile *const file, tagEntry *const entry) -{ - tagResult result; - if (file == NULL || ! file->initialized) - result = TagFailure; - else if (! readTagLine (file)) - result = TagFailure; - else - { - if (entry != NULL) - parseTagLine (file, entry); - result = TagSuccess; - } - return result; -} - -static const char *readFieldValue ( - const tagEntry *const entry, const char *const key) -{ - const char *result = NULL; - int i; - if (strcmp (key, "kind") == 0) - result = entry->kind; - else if (strcmp (key, "file") == 0) - result = EmptyString; - else for (i = 0 ; i < entry->fields.count && result == NULL ; ++i) - if (strcmp (entry->fields.list [i].key, key) == 0) - result = entry->fields.list [i].value; - return result; -} - -static int readTagLineSeek (tagFile *const file, const off_t pos) -{ - int result = 0; - if (fseek (file->fp, pos, SEEK_SET) == 0) - { - result = readTagLine (file); /* read probable partial line */ - if (pos > 0 && result) - result = readTagLine (file); /* read complete line */ - } - return result; -} - -static int nameComparison (tagFile *const file) -{ - int result; - if (file->search.ignorecase) - { - if (file->search.partial) - result = strnuppercmp (file->search.name, file->name.buffer, - file->search.nameLength); - else - result = struppercmp (file->search.name, file->name.buffer); - } - else - { - if (file->search.partial) - result = strncmp (file->search.name, file->name.buffer, - file->search.nameLength); - else - result = strcmp (file->search.name, file->name.buffer); - } - return result; -} - -static void findFirstNonMatchBefore (tagFile *const file) -{ -#define JUMP_BACK 512 - int more_lines; - int comp; - off_t start = file->pos; - off_t pos = start; - do - { - if (pos < (off_t) JUMP_BACK) - pos = 0; - else - pos = pos - JUMP_BACK; - more_lines = readTagLineSeek (file, pos); - comp = nameComparison (file); - } while (more_lines && comp == 0 && pos > 0 && pos < start); -} - -static tagResult findFirstMatchBefore (tagFile *const file) -{ - tagResult result = TagFailure; - int more_lines; - off_t start = file->pos; - findFirstNonMatchBefore (file); - do - { - more_lines = readTagLine (file); - if (nameComparison (file) == 0) - result = TagSuccess; - } while (more_lines && result != TagSuccess && file->pos < start); - return result; -} - -static tagResult findBinary (tagFile *const file) -{ - tagResult result = TagFailure; - off_t lower_limit = 0; - off_t upper_limit = file->size; - off_t last_pos = 0; - off_t pos = upper_limit / 2; - while (result != TagSuccess) - { - if (! readTagLineSeek (file, pos)) - { - /* in case we fell off end of file */ - result = findFirstMatchBefore (file); - break; - } - else if (pos == last_pos) - { - /* prevent infinite loop if we backed up to beginning of file */ - break; - } - else - { - const int comp = nameComparison (file); - last_pos = pos; - if (comp < 0) - { - upper_limit = pos; - pos = lower_limit + ((upper_limit - lower_limit) / 2); - } - else if (comp > 0) - { - lower_limit = pos; - pos = lower_limit + ((upper_limit - lower_limit) / 2); - } - else if (pos == 0) - result = TagSuccess; - else - result = findFirstMatchBefore (file); - } - } - return result; -} - -static tagResult findSequential (tagFile *const file) -{ - tagResult result = TagFailure; - if (file->initialized) - { - while (result == TagFailure && readTagLine (file)) - { - if (nameComparison (file) == 0) - result = TagSuccess; - } - } - return result; -} - -static tagResult find (tagFile *const file, tagEntry *const entry, - const char *const name, const int options) -{ - tagResult result; - if (file->search.name != NULL) - free (file->search.name); - file->search.name = duplicate (name); - file->search.nameLength = strlen (name); - file->search.partial = (options & TAG_PARTIALMATCH) != 0; - file->search.ignorecase = (options & TAG_IGNORECASE) != 0; - fseek (file->fp, 0, SEEK_END); - file->size = ftell (file->fp); - rewind (file->fp); - if ((file->sortMethod == TAG_SORTED && !file->search.ignorecase) || - (file->sortMethod == TAG_FOLDSORTED && file->search.ignorecase)) - { -#ifdef DEBUG - printf ("\n"); -#endif - result = findBinary (file); - } - else - { -#ifdef DEBUG - printf ("\n"); -#endif - result = findSequential (file); - } - - if (result != TagSuccess) - file->search.pos = file->size; - else - { - file->search.pos = file->pos; - if (entry != NULL) - parseTagLine (file, entry); - } - return result; -} - -static tagResult findNext (tagFile *const file, tagEntry *const entry) -{ - tagResult result; - if ((file->sortMethod == TAG_SORTED && !file->search.ignorecase) || - (file->sortMethod == TAG_FOLDSORTED && file->search.ignorecase)) - { - result = tagsNext (file, entry); - if (result == TagSuccess && nameComparison (file) != 0) - result = TagFailure; - } - else - { - result = findSequential (file); - if (result == TagSuccess && entry != NULL) - parseTagLine (file, entry); - } - return result; -} - -/* -* EXTERNAL INTERFACE -*/ - -extern tagFile *tagsOpen (const char *const filePath, tagFileInfo *const info) -{ - return initialize (filePath, info); -} - -extern tagResult tagsSetSortType (tagFile *const file, const sortType type) -{ - tagResult result = TagFailure; - if (file != NULL && file->initialized) - { - file->sortMethod = type; - result = TagSuccess; - } - return result; -} - -extern tagResult tagsFirst (tagFile *const file, tagEntry *const entry) -{ - tagResult result = TagFailure; - if (file != NULL && file->initialized) - { - gotoFirstLogicalTag (file); - result = readNext (file, entry); - } - return result; -} - -extern tagResult tagsNext (tagFile *const file, tagEntry *const entry) -{ - tagResult result = TagFailure; - if (file != NULL && file->initialized) - result = readNext (file, entry); - return result; -} - -extern const char *tagsField (const tagEntry *const entry, const char *const key) -{ - const char *result = NULL; - if (entry != NULL) - result = readFieldValue (entry, key); - return result; -} - -extern tagResult tagsFind (tagFile *const file, tagEntry *const entry, - const char *const name, const int options) -{ - tagResult result = TagFailure; - if (file != NULL && file->initialized) - result = find (file, entry, name, options); - return result; -} - -extern tagResult tagsFindNext (tagFile *const file, tagEntry *const entry) -{ - tagResult result = TagFailure; - if (file != NULL && file->initialized) - result = findNext (file, entry); - return result; -} - -extern tagResult tagsClose (tagFile *const file) -{ - tagResult result = TagFailure; - if (file != NULL && file->initialized) - { - terminate (file); - result = TagSuccess; - } - return result; -} - -/* -* TEST FRAMEWORK -*/ - -#ifdef READTAGS_MAIN - -static const char *TagFileName = "tags"; -static const char *ProgramName; -static int extensionFields; -static int SortOverride; -static sortType SortMethod; - -static void printTag (const tagEntry *entry) -{ - int i; - int first = 1; - const char* separator = ";\""; - const char* const empty = ""; -/* "sep" returns a value only the first time it is evaluated */ -#define sep (first ? (first = 0, separator) : empty) - printf ("%s\t%s\t%s", - entry->name, entry->file, entry->address.pattern); - if (extensionFields) - { - if (entry->kind != NULL && entry->kind [0] != '\0') - printf ("%s\tkind:%s", sep, entry->kind); - if (entry->fileScope) - printf ("%s\tfile:", sep); -#if 0 - if (entry->address.lineNumber > 0) - printf ("%s\tline:%lu", sep, entry->address.lineNumber); -#endif - for (i = 0 ; i < entry->fields.count ; ++i) - printf ("%s\t%s:%s", sep, entry->fields.list [i].key, - entry->fields.list [i].value); - } - putchar ('\n'); -#undef sep -} - -static void findTag (const char *const name, const int options) -{ - tagFileInfo info; - tagEntry entry; - tagFile *const file = tagsOpen (TagFileName, &info); - if (file == NULL) - { - fprintf (stderr, "%s: cannot open tag file: %s: %s\n", - ProgramName, strerror (info.status.error_number), name); - exit (1); - } - else - { - if (SortOverride) - tagsSetSortType (file, SortMethod); - if (tagsFind (file, &entry, name, options) == TagSuccess) - { - do - { - printTag (&entry); - } while (tagsFindNext (file, &entry) == TagSuccess); - } - tagsClose (file); - } -} - -static void listTags (void) -{ - tagFileInfo info; - tagEntry entry; - tagFile *const file = tagsOpen (TagFileName, &info); - if (file == NULL) - { - fprintf (stderr, "%s: cannot open tag file: %s: %s\n", - ProgramName, strerror (info.status.error_number), TagFileName); - exit (1); - } - else - { - while (tagsNext (file, &entry) == TagSuccess) - printTag (&entry); - tagsClose (file); - } -} - -const char *const Usage = - "Find tag file entries matching specified names.\n\n" - "Usage: %s [-ilp] [-s[0|1]] [-t file] [name(s)]\n\n" - "Options:\n" - " -e Include extension fields in output.\n" - " -i Perform case-insensitive matching.\n" - " -l List all tags.\n" - " -p Perform partial matching.\n" - " -s[0|1|2] Override sort detection of tag file.\n" - " -t file Use specified tag file (default: \"tags\").\n" - "Note that options are acted upon as encountered, so order is significant.\n"; - -extern int main (int argc, char **argv) -{ - int options = 0; - int actionSupplied = 0; - int i; - ProgramName = argv [0]; - if (argc == 1) - { - fprintf (stderr, Usage, ProgramName); - exit (1); - } - for (i = 1 ; i < argc ; ++i) - { - const char *const arg = argv [i]; - if (arg [0] != '-') - { - findTag (arg, options); - actionSupplied = 1; - } - else - { - size_t j; - for (j = 1 ; arg [j] != '\0' ; ++j) - { - switch (arg [j]) - { - case 'e': extensionFields = 1; break; - case 'i': options |= TAG_IGNORECASE; break; - case 'p': options |= TAG_PARTIALMATCH; break; - case 'l': listTags (); actionSupplied = 1; break; - - case 't': - if (arg [j+1] != '\0') - { - TagFileName = arg + j + 1; - j += strlen (TagFileName); - } - else if (i + 1 < argc) - TagFileName = argv [++i]; - else - { - fprintf (stderr, Usage, ProgramName); - exit (1); - } - break; - case 's': - SortOverride = 1; - ++j; - if (arg [j] == '\0') - SortMethod = TAG_SORTED; - else if (strchr ("012", arg[j]) != NULL) - SortMethod = (sortType) (arg[j] - '0'); - else - { - fprintf (stderr, Usage, ProgramName); - exit (1); - } - break; - default: - fprintf (stderr, "%s: unknown option: %c\n", - ProgramName, arg[j]); - exit (1); - break; - } - } - } - } - if (! actionSupplied) - { - fprintf (stderr, - "%s: no action specified: specify tag name(s) or -l option\n", - ProgramName); - exit (1); - } - return 0; -} - -#endif - -/* vi:set tabstop=4 shiftwidth=4: */ diff --git a/native/v8_extensions/readtags.h b/native/v8_extensions/readtags.h deleted file mode 100644 index 724f250ad..000000000 --- a/native/v8_extensions/readtags.h +++ /dev/null @@ -1,252 +0,0 @@ -/* -* $Id: readtags.h 443 2006-05-30 04:37:13Z darren $ -* -* Copyright (c) 1996-2003, Darren Hiebert -* -* This source code is released for the public domain. -* -* This file defines the public interface for looking up tag entries in tag -* files. -* -* The functions defined in this interface are intended to provide tag file -* support to a software tool. The tag lookups provided are sufficiently fast -* enough to permit opening a sorted tag file, searching for a matching tag, -* then closing the tag file each time a tag is looked up (search times are -* on the order of hundreths of a second, even for huge tag files). This is -* the recommended use of this library for most tool applications. Adhering -* to this approach permits a user to regenerate a tag file at will without -* the tool needing to detect and resynchronize with changes to the tag file. -* Even for an unsorted 24MB tag file, tag searches take about one second. -*/ -#ifndef READTAGS_H -#define READTAGS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* -* MACROS -*/ - -/* Options for tagsSetSortType() */ -typedef enum { - TAG_UNSORTED, TAG_SORTED, TAG_FOLDSORTED -} sortType ; - -/* Options for tagsFind() */ -#define TAG_FULLMATCH 0x0 -#define TAG_PARTIALMATCH 0x1 - -#define TAG_OBSERVECASE 0x0 -#define TAG_IGNORECASE 0x2 - -/* -* DATA DECLARATIONS -*/ - -typedef enum { TagFailure = 0, TagSuccess = 1 } tagResult; - -struct sTagFile; - -typedef struct sTagFile tagFile; - -/* This structure contains information about the tag file. */ -typedef struct { - - struct { - /* was the tag file successfully opened? */ - int opened; - - /* errno value when 'opened' is false */ - int error_number; - } status; - - /* information about the structure of the tag file */ - struct { - /* format of tag file (1 = original, 2 = extended) */ - short format; - - /* how is the tag file sorted? */ - sortType sort; - } file; - - - /* information about the program which created this tag file */ - struct { - /* name of author of generating program (may be null) */ - const char *author; - - /* name of program (may be null) */ - const char *name; - - /* URL of distribution (may be null) */ - const char *url; - - /* program version (may be null) */ - const char *version; - } program; - -} tagFileInfo; - -/* This structure contains information about an extension field for a tag. - * These exist at the end of the tag in the form "key:value"). - */ -typedef struct { - - /* the key of the extension field */ - const char *key; - - /* the value of the extension field (may be an empty string) */ - const char *value; - -} tagExtensionField; - -/* This structure contains information about a specific tag. */ -typedef struct { - - /* name of tag */ - const char *name; - - /* path of source file containing definition of tag */ - const char *file; - - /* address for locating tag in source file */ - struct { - /* pattern for locating source line - * (may be NULL if not present) */ - const char *pattern; - - /* line number in source file of tag definition - * (may be zero if not known) */ - unsigned long lineNumber; - } address; - - /* kind of tag (may by name, character, or NULL if not known) */ - const char *kind; - - /* is tag of file-limited scope? */ - short fileScope; - - /* miscellaneous extension fields */ - struct { - /* number of entries in `list' */ - unsigned short count; - - /* list of key value pairs */ - tagExtensionField *list; - } fields; - -} tagEntry; - - -/* -* FUNCTION PROTOTYPES -*/ - -/* -* This function must be called before calling other functions in this -* library. It is passed the path to the tag file to read and a (possibly -* null) pointer to a structure which, if not null, will be populated with -* information about the tag file. If successful, the function will return a -* handle which must be supplied to other calls to read information from the -* tag file, and info.status.opened will be set to true. If unsuccessful, -* info.status.opened will be set to false and info.status.error_number will -* be set to the errno value representing the system error preventing the tag -* file from being successfully opened. -*/ -extern tagFile *tagsOpen (const char *const filePath, tagFileInfo *const info); - -/* -* This function allows the client to override the normal automatic detection -* of how a tag file is sorted. Permissible values for `type' are -* TAG_UNSORTED, TAG_SORTED, TAG_FOLDSORTED. Tag files in the new extended -* format contain a key indicating whether or not they are sorted. However, -* tag files in the original format do not contain such a key even when -* sorted, preventing this library from taking advantage of fast binary -* lookups. If the client knows that such an unmarked tag file is indeed -* sorted (or not), it can override the automatic detection. Note that -* incorrect lookup results will result if a tag file is marked as sorted when -* it actually is not. The function will return TagSuccess if called on an -* open tag file or TagFailure if not. -*/ -extern tagResult tagsSetSortType (tagFile *const file, const sortType type); - -/* -* Reads the first tag in the file, if any. It is passed the handle to an -* opened tag file and a (possibly null) pointer to a structure which, if not -* null, will be populated with information about the first tag file entry. -* The function will return TagSuccess another tag entry is found, or -* TagFailure if not (i.e. it reached end of file). -*/ -extern tagResult tagsFirst (tagFile *const file, tagEntry *const entry); - -/* -* Step to the next tag in the file, if any. It is passed the handle to an -* opened tag file and a (possibly null) pointer to a structure which, if not -* null, will be populated with information about the next tag file entry. The -* function will return TagSuccess another tag entry is found, or TagFailure -* if not (i.e. it reached end of file). It will always read the first tag in -* the file immediately after calling tagsOpen(). -*/ -extern tagResult tagsNext (tagFile *const file, tagEntry *const entry); - -/* -* Retrieve the value associated with the extension field for a specified key. -* It is passed a pointer to a structure already populated with values by a -* previous call to tagsNext(), tagsFind(), or tagsFindNext(), and a string -* containing the key of the desired extension field. If no such field of the -* specified key exists, the function will return null. -*/ -extern const char *tagsField (const tagEntry *const entry, const char *const key); - -/* -* Find the first tag matching `name'. The structure pointed to by `entry' -* will be populated with information about the tag file entry. If a tag file -* is sorted using the C locale, a binary search algorithm is used to search -* the tag file, resulting in very fast tag lookups, even in huge tag files. -* Various options controlling the matches can be combined by bit-wise or-ing -* certain values together. The available values are: -* -* TAG_PARTIALMATCH -* Tags whose leading characters match `name' will qualify. -* -* TAG_FULLMATCH -* Only tags whose full lengths match `name' will qualify. -* -* TAG_IGNORECASE -* Matching will be performed in a case-insenstive manner. Note that -* this disables binary searches of the tag file. -* -* TAG_OBSERVECASE -* Matching will be performed in a case-senstive manner. Note that -* this enables binary searches of the tag file. -* -* The function will return TagSuccess if a tag matching the name is found, or -* TagFailure if not. -*/ -extern tagResult tagsFind (tagFile *const file, tagEntry *const entry, const char *const name, const int options); - -/* -* Find the next tag matching the name and options supplied to the most recent -* call to tagsFind() for the same tag file. The structure pointed to by -* `entry' will be populated with information about the tag file entry. The -* function will return TagSuccess if another tag matching the name is found, -* or TagFailure if not. -*/ -extern tagResult tagsFindNext (tagFile *const file, tagEntry *const entry); - -/* -* Call tagsTerminate() at completion of reading the tag file, which will -* close the file and free any internal memory allocated. The function will -* return TagFailure is no file is currently open, TagSuccess otherwise. -*/ -extern tagResult tagsClose (tagFile *const file); - -#ifdef __cplusplus -}; -#endif - -#endif - -/* vi:set tabstop=4 shiftwidth=4: */ diff --git a/native/v8_extensions/tags.h b/native/v8_extensions/tags.h deleted file mode 100644 index e8c6627bf..000000000 --- a/native/v8_extensions/tags.h +++ /dev/null @@ -1,26 +0,0 @@ -#include "include/cef_base.h" -#include "include/cef_v8.h" -#include "readtags.h" - -namespace v8_extensions { - - class Tags : public CefV8Handler { - public: - Tags(); - void CreateContextBinding(CefRefPtr context); - virtual bool Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) OVERRIDE; - - // Provide the reference counting implementation for this class. - IMPLEMENT_REFCOUNTING(Tags); - - private: - Tags(Tags const&); - void operator=(Tags const&); - CefRefPtr ParseEntry(tagEntry entry); - }; - -} diff --git a/native/v8_extensions/tags.mm b/native/v8_extensions/tags.mm deleted file mode 100644 index 2e826d323..000000000 --- a/native/v8_extensions/tags.mm +++ /dev/null @@ -1,116 +0,0 @@ -#import "tags.h" -#import - -namespace v8_extensions { - - Tags::Tags() : CefV8Handler() { - } - - void Tags::CreateContextBinding(CefRefPtr context) { - const char* methodNames[] = { "find", "getAllTagsAsync" }; - - CefRefPtr nativeObject = CefV8Value::CreateObject(NULL); - int arrayLength = sizeof(methodNames) / sizeof(const char *); - for (int i = 0; i < arrayLength; i++) { - const char *functionName = methodNames[i]; - CefRefPtr function = CefV8Value::CreateFunction(functionName, this); - nativeObject->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE); - } - - CefRefPtr global = context->GetGlobal(); - global->SetValue("$tags", nativeObject, V8_PROPERTY_ATTRIBUTE_NONE); - } - - CefRefPtr Tags::ParseEntry(tagEntry entry) { - CefRefPtr tagEntry = CefV8Value::CreateObject(NULL); - tagEntry->SetValue("name", CefV8Value::CreateString(entry.name), V8_PROPERTY_ATTRIBUTE_NONE); - tagEntry->SetValue("file", CefV8Value::CreateString(entry.file), V8_PROPERTY_ATTRIBUTE_NONE); - if (entry.address.pattern) { - tagEntry->SetValue("pattern", CefV8Value::CreateString(entry.address.pattern), V8_PROPERTY_ATTRIBUTE_NONE); - } - return tagEntry; - } - - bool Tags::Execute(const CefString& name, - CefRefPtr object, - const CefV8ValueList& arguments, - CefRefPtr& retval, - CefString& exception) { - - @autoreleasepool { - if (name == "find") { - std::string path = arguments[0]->GetStringValue().ToString(); - std::string tag = arguments[1]->GetStringValue().ToString(); - tagFileInfo info; - tagFile* tagFile; - tagFile = tagsOpen(path.c_str(), &info); - if (info.status.opened) { - tagEntry entry; - std::vector> entries; - if (tagsFind(tagFile, &entry, tag.c_str(), TAG_FULLMATCH | TAG_OBSERVECASE) == TagSuccess) { - entries.push_back(ParseEntry(entry)); - while (tagsFindNext(tagFile, &entry) == TagSuccess) { - entries.push_back(ParseEntry(entry)); - } - } - - retval = CefV8Value::CreateArray(entries.size()); - for (int i = 0; i < entries.size(); i++) { - retval->SetValue(i, entries[i]); - } - tagsClose(tagFile); - } - return true; - } - - if (name == "getAllTagsAsync") { - std::string path = arguments[0]->GetStringValue().ToString(); - CefRefPtr callback = arguments[1]; - CefRefPtr context = CefV8Context::GetCurrentContext(); - - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - dispatch_async(queue, ^{ - tagFileInfo info; - tagFile* tagFile; - tagFile = tagsOpen(path.c_str(), &info); - std::vector entries; - - if (info.status.opened) { - tagEntry entry; - while (tagsNext(tagFile, &entry) == TagSuccess) { - entry.name = strdup(entry.name); - entry.file = strdup(entry.file); - if (entry.address.pattern) { - entry.address.pattern = strdup(entry.address.pattern); - } - entries.push_back(entry); - } - tagsClose(tagFile); - } - - dispatch_queue_t mainQueue = dispatch_get_main_queue(); - dispatch_async(mainQueue, ^{ - context->Enter(); - CefRefPtr v8Tags = CefV8Value::CreateArray(entries.size()); - for (int i = 0; i < entries.size(); i++) { - v8Tags->SetValue(i, ParseEntry(entries[i])); - free((void*)entries[i].name); - free((void*)entries[i].file); - if (entries[i].address.pattern) { - free((void*)entries[i].address.pattern); - } - } - CefV8ValueList callbackArgs; - callbackArgs.push_back(v8Tags); - callback->ExecuteFunction(callback, callbackArgs); - context->Exit(); - }); - }); - return true; - } - - return false; - } - } - -} diff --git a/package.json b/package.json index 1893b5e86..5d0dfb7ff 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,23 @@ "version" : "0.0.0", "dependencies": { - "coffee-script": "1.5" + "coffee-script": "1.5", + "ctags": "0.3.0", + "oniguruma": "0.8.0", + "mkdirp": "0.3.5", + "git-utils": "0.8.0", + "underscore": "1.4.4", + "d3": "3.0.8", + "coffee-cache": "0.1.0", + "pegjs": "0.7.0", + "async": "0.2.6", + "spellchecker": "0.2.0", + "plist": "git://github.com/nathansobo/node-plist.git", + "space-pen": "git://github.com/nathansobo/space-pen.git" }, + "private": true, + "scripts": { "preinstall": "true" } diff --git a/prebuilt-cef b/prebuilt-cef index 3ced0be18..59d147be2 160000 --- a/prebuilt-cef +++ b/prebuilt-cef @@ -1 +1 @@ -Subproject commit 3ced0be18717e65fcf4d832bded37156cd0710e7 +Subproject commit 59d147be26fc404ed0522729e363a324bff98b66 diff --git a/script/bootstrap b/script/bootstrap index 1b9a93df1..4db2c1279 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -18,6 +18,15 @@ exit_unless_npm_exists() { exit_unless_xcode_exists exit_unless_npm_exists -npm install +npm install npm --silent + +NODE_DIR="$HOME/.cefode-gyp" +NODE_VERSION="0.10.1" +NODE_URL="https://gh-contractor-zcbenz.s3.amazonaws.com/cefode2/dist" +if [ ! -d "node_modules/node-gyp" ]; then + ./node_modules/.bin/npm install node-gyp --silent + HOME="$NODE_DIR" ./node_modules/.bin/node-gyp install --target="$NODE_VERSION" --dist-url="$NODE_URL" --arch=ia32 +fi +HOME="$NODE_DIR" ./node_modules/.bin/npm install --target="$NODE_VERSION" --arch=ia32 --silent git submodule --quiet sync git submodule --quiet update --recursive --init diff --git a/script/compile-cson.coffee b/script/compile-cson.coffee index 42d35c93d..5095349d8 100644 --- a/script/compile-cson.coffee +++ b/script/compile-cson.coffee @@ -8,7 +8,7 @@ unless inputFile?.length > 0 outputFile = process.argv[3] unless outputFile?.length > 0 - console.error("Output file must be second arguments") + console.error("Output file must be second argument") process.exit(1) contents = fs.readFileSync(inputFile)?.toString() ? '' diff --git a/script/compile-less b/script/compile-less new file mode 100644 index 000000000..8d334d2da --- /dev/null +++ b/script/compile-less @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +# Because of the way xcodebuild invokes external scripts we need to load +# The Setup's environment ourselves. If this isn't done, things like the +# node shim won't be able to find the stuff they need. + +node --version > /dev/null 2>&1 || { + if [ -e /opt/github/env.sh ]; then + source /opt/github/env.sh + else + # Try Constructicon's PATH. + export PATH="/usr/local/Cellar/node/0.8.21/bin:${PATH}" + fi +} + +INPUT_FILE="${1}" +OUTPUT_FILE="${2}" + +node_modules/.bin/coffee script/compile-less.coffee -- "${INPUT_FILE}" "${OUTPUT_FILE}" diff --git a/script/compile-less.coffee b/script/compile-less.coffee new file mode 100644 index 000000000..805d477d2 --- /dev/null +++ b/script/compile-less.coffee @@ -0,0 +1,25 @@ +# Hack since the vendored less is in browser mode +global.window = {} +global.document = + getElementsByTagName: -> [] +global.location = + port: 80 + +{less} = require '../vendor/less' +fs = require 'fs' + +inputFile = process.argv[2] +unless inputFile?.length > 0 + console.error("Input file must be first argument") + process.exit(1) + +outputFile = process.argv[3] +unless outputFile?.length > 0 + console.error("Output file must be second argument") + process.exit(1) + +contents = fs.readFileSync(inputFile)?.toString() ? '' +(new less.Parser).parse contents, (e, tree) -> + console.error(e.stack or e) if e + process.exit(1) if e + fs.writeFileSync(outputFile, tree.toCSS()) diff --git a/script/copy-files-to-bundle b/script/copy-files-to-bundle index c4eed5d02..e3f6de315 100755 --- a/script/copy-files-to-bundle +++ b/script/copy-files-to-bundle @@ -7,4 +7,9 @@ COMPILED_SOURCES_DIR="${1}" RESOUCES_PATH="$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH" # Copy non-coffee files into bundle -rsync --archive --recursive --exclude="src/**/*.coffee" --exclude="src/**/*.cson" src static vendor spec benchmark themes dot-atom atom.sh "${COMPILED_SOURCES_DIR}/" "$RESOUCES_PATH" +rsync --archive --recursive \ + --exclude="src/**/*.coffee" --exclude="src/**/*.cson" \ + --exclude="src/**/*.less" --exclude="static/*.less" \ + --exclude="node_modules/less" \ + node_modules src static vendor spec benchmark themes dot-atom atom.sh \ + "${COMPILED_SOURCES_DIR}/" "$RESOUCES_PATH" diff --git a/script/generate-sources-gypi b/script/generate-sources-gypi index 266fde180..014525021 100755 --- a/script/generate-sources-gypi +++ b/script/generate-sources-gypi @@ -27,6 +27,9 @@ $(find_files '*.coffee' | file_list) 'cson_sources': [ $(find_files '*.cson' | file_list) ], + 'less_sources': [ +$(find src static -type file -name '*.less' | file_list) + ], }, } EOF diff --git a/script/translate-crash-log-addresses.coffee b/script/translate-crash-log-addresses.coffee new file mode 100755 index 000000000..7fb01532b --- /dev/null +++ b/script/translate-crash-log-addresses.coffee @@ -0,0 +1,56 @@ +#!/usr/bin/env coffee +# Usage: +# Copy the crash log into pasteboard and then run +# pbpaste | ./script/translate-crash-log-addresses.coffee + +atos = (addresses, callback) -> + path = require 'path' + exec = require('child_process').exec + + cwd = path.join __dirname, '..' + exec 'atos -o cef/Release/libcef.dylib -arch i386 '.concat(addresses...), cwd: cwd, (error, stdout, stderr) -> + throw error if error? + callback stdout.split('\n') + +parse_stack_trace = (raw) -> + lines = {} + addresses = [] + for line in raw + columns = line.split /\ +/ + if columns[1] == 'libcef.dylib' and /0x[a-f0-9]+/.test columns[3] + lines[columns[0]] = addresses.length + addresses.push '0x' + parseInt(columns[5]).toString(16) + ' ' + + atos addresses, (parsed) -> + for line in raw + columns = line.split /\ +/ + frame = columns[0] + if lines[frame]? + console.log frame, parsed[lines[frame]] + else + console.log line + +parse_log_file = (content) -> + state = 'start' + stack_trace = [] + lines = content.split /\r?\n/ + + for line in lines + if state == 'start' + if /Thread \d+ Crashed::/.test line + console.log line + state = 'parse' + else if state == 'parse' + break if line == '' + stack_trace.push line + + parse_stack_trace stack_trace + +input = '' +process.stdin.resume() +process.stdin.setEncoding 'utf8' +process.stdin.on 'data', (chunk) -> + input += chunk +process.stdin.on 'end', -> + parse_log_file input + diff --git a/script/update-cefode b/script/update-cefode new file mode 100755 index 000000000..a715242c6 --- /dev/null +++ b/script/update-cefode @@ -0,0 +1,48 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )/.." + +if [[ $1 == '-s' ]]; then + SYMBOLS=1 + shift +fi + +if [ -z $1 ]; then + TARGET='cef' +else + TARGET=$1 +fi + +DISTURL="https://gh-contractor-zcbenz.s3.amazonaws.com/cefode2/prebuilt-cef" +CEF_BASENAME="cef_binary_3.1423.1133_macosx" +CEF_SYMBOLS_BASENAME="${CEF_BASENAME}_symbols" + +TEMP_DIR=$(mktemp -d -t prebuilt-cef-download.XXXXXX) +trap "rm -rf \"${TEMP_DIR}\"" EXIT + +# Latest version +if ! LATEST_VERSION=$(curl -fsSkL $DISTURL/version); then + exit 1; +fi + +# Current version +CURRENT_VERSION=`cat cef/version 2>&1` + +if [[ $LATEST_VERSION != $CURRENT_VERSION ]]; then + echo "Downloading/extracting cefode2 u${LATEST_VERSION}..." + curl --progress-bar "${DISTURL}/cef_binary_latest.zip" > "${TEMP_DIR}/cef.zip" + unzip -q "${TEMP_DIR}/cef.zip" -d "${TEMP_DIR}" + [ -e "${TARGET}" ] && rm -rf "${TARGET}" + mv "${TEMP_DIR}/${CEF_BASENAME}" "${TARGET}" + echo ${LATEST_VERSION} > 'cef/version' +fi + +if [[ "${SYMBOLS}" != "1" ]]; then + exit 0 +fi + +echo "Downloading/extracting symbols for cefode2 u${LATEST_VERSION}..." +curl --progress-bar "${DISTURL}/cef_binary_latest_symbols.zip" > "${TEMP_DIR}/symbols.zip" +unzip -q "${TEMP_DIR}/symbols.zip" -d "${TEMP_DIR}" +mv "${TEMP_DIR}/${CEF_SYMBOLS_BASENAME}"/* "${TARGET}/Release" + diff --git a/script/update-node b/script/update-node new file mode 100755 index 000000000..bbbb6d9e3 --- /dev/null +++ b/script/update-node @@ -0,0 +1,32 @@ +#!/bin/bash + +set -e + +cd "$(dirname $0)/.." + +NODE_VERSION=v0.10.1 +[ -z $1 ] || NODE_VERSION=$1 + +# Test whether we need update. +if [ -f "node/node" ] && [[ `node/node --version` == $NODE_VERSION ]] ; then + exit 0 +fi + +case $OSTYPE in + darwin*) NODE_PLATFORM=darwin ;; + linux*) NODE_PLATFORM=linux ;; + *) echo "Unsupported platform $OSTYPE" && exit 1 ;; +esac + +NODE_DIST_NAME="node-$NODE_VERSION-$NODE_PLATFORM-x86" + +# Download node and untar +NODE_TARBALL_URL="https://gh-contractor-zcbenz.s3.amazonaws.com/node/dist/$NODE_DIST_NAME.tar.gz" +TARGET_DIR='node' +[ -d "$TARGET_DIR" ] || mkdir "$TARGET_DIR" +cd "$TARGET_DIR" +curl -fsSkL $NODE_TARBALL_URL | tar -zx || exit 1 + +cp "$NODE_DIST_NAME/bin/node" . +rm -rf "$NODE_DIST_NAME" + diff --git a/spec/app/atom-package-spec.coffee b/spec/app/atom-package-spec.coffee deleted file mode 100644 index 469eb59e4..000000000 --- a/spec/app/atom-package-spec.coffee +++ /dev/null @@ -1,78 +0,0 @@ -RootView = require 'root-view' -AtomPackage = require 'atom-package' -fs = require 'fs' - -describe "AtomPackage", -> - [packageMainModule, pack] = [] - - beforeEach -> - pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-activation-events')) - pack.load() - - describe ".load()", -> - describe "if the package's metadata has a `deferredDeserializers` array", -> - it "requires the package's main module attempting to use deserializers named in the array", -> - expect(pack.mainModule).toBeNull() - object = deserialize(deserializer: 'Foo', data: "Hello") - expect(object.constructor.name).toBe 'Foo' - expect(object.data).toBe 'Hello' - expect(pack.mainModule).toBeDefined() - expect(pack.mainModule.activateCallCount).toBe 0 - - describe ".activate()", -> - beforeEach -> - window.rootView = new RootView - packageMainModule = require 'fixtures/packages/package-with-activation-events/main' - spyOn(packageMainModule, 'activate').andCallThrough() - - describe "when the package metadata includes activation events", -> - beforeEach -> - pack.activate() - - it "defers activating the package until an activation event bubbles to the root view", -> - expect(packageMainModule.activate).not.toHaveBeenCalled() - rootView.trigger 'activation-event' - expect(packageMainModule.activate).toHaveBeenCalled() - - it "triggers the activation event on all handlers registered during activation", -> - rootView.open('sample.js') - editor = rootView.getActiveView() - eventHandler = jasmine.createSpy("activation-event") - editor.command 'activation-event', eventHandler - editor.trigger 'activation-event' - expect(packageMainModule.activate.callCount).toBe 1 - expect(packageMainModule.activationEventCallCount).toBe 1 - expect(eventHandler.callCount).toBe 1 - editor.trigger 'activation-event' - expect(packageMainModule.activationEventCallCount).toBe 2 - expect(eventHandler.callCount).toBe 2 - expect(packageMainModule.activate.callCount).toBe 1 - - describe "when the package does not specify a main module", -> - describe "when the package has an index.coffee", -> - it "uses index.coffee as the main module", -> - pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-module')) - packageMainModule = require 'fixtures/packages/package-with-module' - spyOn(packageMainModule, 'activate').andCallThrough() - - expect(packageMainModule.activate).not.toHaveBeenCalled() - pack.load() - pack.activate() - expect(packageMainModule.activate).toHaveBeenCalled() - - describe "when the package doesn't have an index.coffee", -> - it "does not throw an exception or log an error", -> - spyOn(console, "error") - spyOn(console, "warn") - pack = new AtomPackage(fs.resolve(config.packageDirPaths..., 'package-with-keymaps-manifest')) - - expect(-> pack.load()).not.toThrow() - expect(console.error).not.toHaveBeenCalled() - expect(console.warn).not.toHaveBeenCalled() - - describe "when a package is activated", -> - it "loads config defaults based on the `configDefaults` key", -> - expect(config.get('package-with-module.numbers.one')).toBeUndefined() - window.loadPackage("package-with-module") - expect(config.get('package-with-module.numbers.one')).toBe 1 - expect(config.get('package-with-module.numbers.two')).toBe 2 diff --git a/spec/app/atom-spec.coffee b/spec/app/atom-spec.coffee index 3b007f125..8b32d3d79 100644 --- a/spec/app/atom-spec.coffee +++ b/spec/app/atom-spec.coffee @@ -1,137 +1,245 @@ +$ = require 'jquery' RootView = require 'root-view' {$$} = require 'space-pen' +fs = require 'fs-utils' describe "the `atom` global", -> beforeEach -> window.rootView = new RootView - describe "when a package is built and loaded", -> - [extension, stylesheetPath] = [] + describe "package lifecycle methods", -> + describe ".loadPackage(id)", -> + describe "when the package has deferred deserializers", -> + it "requires the package's main module if one of its deferred deserializers is referenced", -> + pack = atom.loadPackage('package-with-activation-events') + expect(pack.mainModule).toBeNull() + object = deserialize({deserializer: 'Foo', data: 5}) + expect(pack.mainModule).toBeDefined() + expect(object.constructor.name).toBe 'Foo' + expect(object.data).toBe 5 - beforeEach -> - extension = require "package-with-module" - stylesheetPath = require.resolve("fixtures/packages/package-with-module/stylesheets/styles.css") + describe ".activatePackage(id)", -> + describe "atom packages", -> + describe "when the package has a main module", -> + describe "when the metadata specifies a main module path˜", -> + it "requires the module at the specified path", -> + mainModule = require('package-with-main/main-module') + spyOn(mainModule, 'activate') + pack = atom.activatePackage('package-with-main') + expect(mainModule.activate).toHaveBeenCalled() + expect(pack.mainModule).toBe mainModule - afterEach -> - removeStylesheet(stylesheetPath) + describe "when the metadata does not specify a main module", -> + it "requires index.coffee", -> + indexModule = require('package-with-index/index') + spyOn(indexModule, 'activate') + pack = atom.activatePackage('package-with-index') + expect(indexModule.activate).toHaveBeenCalled() + expect(pack.mainModule).toBe indexModule - it "requires and activates the package's main module if it exists", -> - spyOn(atom, 'activateAtomPackage').andCallThrough() - window.loadPackage("package-with-module") - expect(atom.activateAtomPackage).toHaveBeenCalled() + it "assigns config defaults from the module", -> + expect(config.get('package-with-config-defaults.numbers.one')).toBeUndefined() + atom.activatePackage('package-with-config-defaults') + expect(config.get('package-with-config-defaults.numbers.one')).toBe 1 + expect(config.get('package-with-config-defaults.numbers.two')).toBe 2 - it "logs warning instead of throwing an exception if a package fails to load", -> - config.set("core.disabledPackages", []) - spyOn(console, "warn") - expect(-> window.loadPackage("package-that-throws-an-exception")).not.toThrow() - expect(console.warn).toHaveBeenCalled() + describe "when the package metadata includes activation events", -> + [mainModule, pack] = [] - describe "keymap loading", -> - describe "when package.json does not contain a 'keymaps' manifest", -> - it "loads all the .cson/.json files in the keymaps directory", -> - element1 = $$ -> @div class: 'test-1' - element2 = $$ -> @div class: 'test-2' - element3 = $$ -> @div class: 'test-3' + beforeEach -> + mainModule = require 'package-with-activation-events/index' + spyOn(mainModule, 'activate').andCallThrough() + AtomPackage = require 'atom-package' + spyOn(AtomPackage.prototype, 'requireMainModule').andCallThrough() + pack = atom.activatePackage('package-with-activation-events') - expect(keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined() - expect(keymap.bindingsForElement(element2)['ctrl-z']).toBeUndefined() - expect(keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined() + it "defers requiring/activating the main module until an activation event bubbles to the root view", -> + expect(pack.requireMainModule).not.toHaveBeenCalled() + expect(mainModule.activate).not.toHaveBeenCalled() + rootView.trigger 'activation-event' + expect(mainModule.activate).toHaveBeenCalled() - window.loadPackage("package-with-module") + it "triggers the activation event on all handlers registered during activation", -> + rootView.open() + editor = rootView.getActiveView() + eventHandler = jasmine.createSpy("activation-event") + editor.command 'activation-event', eventHandler + editor.trigger 'activation-event' + expect(mainModule.activate.callCount).toBe 1 + expect(mainModule.activationEventCallCount).toBe 1 + expect(eventHandler.callCount).toBe 1 + editor.trigger 'activation-event' + expect(mainModule.activationEventCallCount).toBe 2 + expect(eventHandler.callCount).toBe 2 + expect(mainModule.activate.callCount).toBe 1 - expect(keymap.bindingsForElement(element1)['ctrl-z']).toBe "test-1" - expect(keymap.bindingsForElement(element2)['ctrl-z']).toBe "test-2" - expect(keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined() + describe "when the package has no main module", -> + it "does not throw an exception", -> + spyOn(console, "error") + spyOn(console, "warn").andCallThrough() + expect(-> atom.activatePackage('package-without-module')).not.toThrow() + expect(console.error).not.toHaveBeenCalled() + expect(console.warn).not.toHaveBeenCalled() - describe "when package.json contains a 'keymaps' manifest", -> - it "loads only the keymaps specified by the manifest, in the specified order", -> - element1 = $$ -> @div class: 'test-1' - element3 = $$ -> @div class: 'test-3' + it "passes the activate method the package's previously serialized state if it exists", -> + pack = atom.activatePackage("package-with-serialization") + expect(pack.mainModule.someNumber).not.toBe 77 + pack.mainModule.someNumber = 77 + atom.deactivatePackage("package-with-serialization") + spyOn(pack.mainModule, 'activate').andCallThrough() + atom.activatePackage("package-with-serialization") + expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77}) - expect(keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined() + it "logs warning instead of throwing an exception if the package fails to load", -> + config.set("core.disabledPackages", []) + spyOn(console, "warn") + expect(-> atom.activatePackage("package-that-throws-an-exception")).not.toThrow() + expect(console.warn).toHaveBeenCalled() - window.loadPackage("package-with-keymaps-manifest") + describe "keymap loading", -> + describe "when the metadata does not contain a 'keymaps' manifest", -> + it "loads all the .cson/.json files in the keymaps directory", -> + element1 = $$ -> @div class: 'test-1' + element2 = $$ -> @div class: 'test-2' + element3 = $$ -> @div class: 'test-3' - expect(keymap.bindingsForElement(element1)['ctrl-z']).toBe 'keymap-1' - expect(keymap.bindingsForElement(element1)['ctrl-n']).toBe 'keymap-2' - expect(keymap.bindingsForElement(element3)['ctrl-y']).toBeUndefined() + expect(keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined() + expect(keymap.bindingsForElement(element2)['ctrl-z']).toBeUndefined() + expect(keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined() - it "loads stylesheets associated with the package", -> - stylesheetPath = require.resolve("fixtures/packages/package-with-module/stylesheets/styles.css") - expect(stylesheetElementForId(stylesheetPath).length).toBe 0 - window.loadPackage("package-with-module") - expect(stylesheetElementForId(stylesheetPath).length).toBe 1 + atom.activatePackage("package-with-keymaps") - describe ".loadPackages()", -> - beforeEach -> - spyOn(syntax, 'addGrammar') + expect(keymap.bindingsForElement(element1)['ctrl-z']).toBe "test-1" + expect(keymap.bindingsForElement(element2)['ctrl-z']).toBe "test-2" + expect(keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined() - it "aborts the worker when all packages have been loaded", -> - LoadTextMatePackagesTask = require 'load-text-mate-packages-task' - spyOn(LoadTextMatePackagesTask.prototype, 'abort').andCallThrough() - eventHandler = jasmine.createSpy('eventHandler') - syntax.on 'grammars-loaded', eventHandler - config.get("core.disabledPackages").push('textmate-package.tmbundle', 'package-with-snippets') - atom.loadPackages() + describe "when the metadata contains a 'keymaps' manifest", -> + it "loads only the keymaps specified by the manifest, in the specified order", -> + element1 = $$ -> @div class: 'test-1' + element3 = $$ -> @div class: 'test-3' - waitsFor "all packages to load", 5000, -> eventHandler.callCount > 0 + expect(keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined() - runs -> - expect(LoadTextMatePackagesTask.prototype.abort).toHaveBeenCalled() - expect(LoadTextMatePackagesTask.prototype.abort.calls.length).toBe 1 + atom.activatePackage("package-with-keymaps-manifest") - describe "package lifecycle", -> - describe "activation", -> - it "calls activate on the package main with its previous state", -> - pack = window.loadPackage('package-with-module') - spyOn(pack.mainModule, 'activate') + expect(keymap.bindingsForElement(element1)['ctrl-z']).toBe 'keymap-1' + expect(keymap.bindingsForElement(element1)['ctrl-n']).toBe 'keymap-2' + expect(keymap.bindingsForElement(element3)['ctrl-y']).toBeUndefined() - serializedState = rootView.serialize() - rootView.deactivate() - RootView.deserialize(serializedState) - window.loadPackage('package-with-module') + describe "stylesheet loading", -> + describe "when the metadata contains a 'stylesheets' manifest", -> + it "loads stylesheets from the stylesheets directory as specified by the manifest", -> + one = fs.resolveOnLoadPath("package-with-stylesheets-manifest/stylesheets/1.css") + two = fs.resolveOnLoadPath("package-with-stylesheets-manifest/stylesheets/2.less") + three = fs.resolveOnLoadPath("package-with-stylesheets-manifest/stylesheets/3.css") + expect(stylesheetElementForId(one)).not.toExist() + expect(stylesheetElementForId(two)).not.toExist() + expect(stylesheetElementForId(three)).not.toExist() - expect(pack.mainModule.activate).toHaveBeenCalledWith(someNumber: 1) + atom.activatePackage("package-with-stylesheets-manifest") - describe "deactivation", -> - it "deactivates and removes the package module from the package module map", -> - pack = window.loadPackage('package-with-module') - expect(atom.activatedAtomPackages.length).toBe 1 - spyOn(pack.mainModule, "deactivate").andCallThrough() - atom.deactivateAtomPackages() - expect(pack.mainModule.deactivate).toHaveBeenCalled() - expect(atom.activatedAtomPackages.length).toBe 0 + expect(stylesheetElementForId(one)).toExist() + expect(stylesheetElementForId(two)).toExist() + expect(stylesheetElementForId(three)).not.toExist() + expect($('#jasmine-content').css('font-size')).toBe '1px' - describe "serialization", -> - it "uses previous serialization state on packages whose activation has been deferred", -> - atom.atomPackageStates['package-with-activation-events'] = {previousData: 'exists'} - unactivatedPackage = window.loadPackage('package-with-activation-events') - activatedPackage = window.loadPackage('package-with-module') + describe "when the metadata does not contain a 'stylesheets' manifest", -> + it "loads all stylesheets from the stylesheets directory", -> + one = fs.resolveOnLoadPath("package-with-stylesheets/stylesheets/1.css") + two = fs.resolveOnLoadPath("package-with-stylesheets/stylesheets/2.less") + three = fs.resolveOnLoadPath("package-with-stylesheets/stylesheets/3.css") + expect(stylesheetElementForId(one)).not.toExist() + expect(stylesheetElementForId(two)).not.toExist() + expect(stylesheetElementForId(three)).not.toExist() - expect(atom.serializeAtomPackages()).toEqual - 'package-with-module': - 'someNumber': 1 - 'package-with-activation-events': - 'previousData': 'exists' + atom.activatePackage("package-with-stylesheets") + expect(stylesheetElementForId(one)).toExist() + expect(stylesheetElementForId(two)).toExist() + expect(stylesheetElementForId(three)).toExist() + expect($('#jasmine-content').css('font-size')).toBe '3px' - # ensure serialization occurs when the packageis activated - unactivatedPackage.deferActivation = false - unactivatedPackage.activate() - expect(atom.serializeAtomPackages()).toEqual - 'package-with-module': - 'someNumber': 1 - 'package-with-activation-events': - 'previousData': 'overwritten' + describe "grammar loading", -> + it "loads the package's grammars", -> + atom.activatePackage('package-with-grammars') + expect(syntax.selectGrammar('a.alot').name).toBe 'Alot' + expect(syntax.selectGrammar('a.alittle').name).toBe 'Alittle' - it "absorbs exceptions that are thrown by the package module's serialize methods", -> - spyOn(console, 'error') - window.loadPackage('package-with-module', activateImmediately: true) - window.loadPackage('package-with-serialize-error', activateImmediately: true) + describe "scoped-property loading", -> + it "loads the scoped properties", -> + atom.activatePackage("package-with-scoped-properties") + expect(syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a' - packageStates = atom.serializeAtomPackages() - expect(packageStates['package-with-module']).toEqual someNumber: 1 - expect(packageStates['package-with-serialize-error']).toBeUndefined() - expect(console.error).toHaveBeenCalled() + describe "textmate packages", -> + it "loads the package's grammars", -> + expect(syntax.selectGrammar("file.rb").name).toBe "Null Grammar" + atom.activatePackage('ruby.tmbundle', sync: true) + expect(syntax.selectGrammar("file.rb").name).toBe "Ruby" + + it "translates the package's scoped properties to Atom terms", -> + expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined() + atom.activatePackage('ruby.tmbundle', sync: true) + expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# ' + + describe ".deactivatePackage(id)", -> + describe "atom packages", -> + it "calls `deactivate` on the package's main module", -> + pack = atom.activatePackage("package-with-deactivate") + expect(atom.isPackageActive("package-with-deactivate")).toBeTruthy() + spyOn(pack.mainModule, 'deactivate').andCallThrough() + + atom.deactivatePackage("package-with-deactivate") + expect(pack.mainModule.deactivate).toHaveBeenCalled() + expect(atom.isPackageActive("package-with-module")).toBeFalsy() + + it "absorbs exceptions that are thrown by the package module's serialize methods", -> + spyOn(console, 'error') + atom.activatePackage('package-with-serialize-error', immediate: true) + atom.activatePackage('package-with-serialization', immediate: true) + atom.deactivatePackages() + expect(atom.packageStates['package-with-serialize-error']).toBeUndefined() + expect(atom.packageStates['package-with-serialization']).toEqual someNumber: 1 + expect(console.error).toHaveBeenCalled() + + it "removes the package's grammars", -> + atom.activatePackage('package-with-grammars') + atom.deactivatePackage('package-with-grammars') + expect(syntax.selectGrammar('a.alot').name).toBe 'Null Grammar' + expect(syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar' + + it "removes the package's keymaps", -> + atom.activatePackage('package-with-keymaps') + atom.deactivatePackage('package-with-keymaps') + expect(keymap.bindingsForElement($$ -> @div class: 'test-1')['ctrl-z']).toBeUndefined() + expect(keymap.bindingsForElement($$ -> @div class: 'test-2')['ctrl-z']).toBeUndefined() + + it "removes the package's stylesheets", -> + atom.activatePackage('package-with-stylesheets') + atom.deactivatePackage('package-with-stylesheets') + one = fs.resolveOnLoadPath("package-with-stylesheets/stylesheets/1.css") + two = fs.resolveOnLoadPath("package-with-stylesheets/stylesheets/2.less") + three = fs.resolveOnLoadPath("package-with-stylesheets/stylesheets/3.css") + expect(stylesheetElementForId(one)).not.toExist() + expect(stylesheetElementForId(two)).not.toExist() + expect(stylesheetElementForId(three)).not.toExist() + + it "removes the package's scoped-properties", -> + atom.activatePackage("package-with-scoped-properties") + expect(syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a' + atom.deactivatePackage("package-with-scoped-properties") + expect(syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined() + + describe "texmate packages", -> + it "removes the package's grammars", -> + expect(syntax.selectGrammar("file.rb").name).toBe "Null Grammar" + atom.activatePackage('ruby.tmbundle', sync: true) + expect(syntax.selectGrammar("file.rb").name).toBe "Ruby" + atom.deactivatePackage('ruby.tmbundle') + expect(syntax.selectGrammar("file.rb").name).toBe "Null Grammar" + + it "removes the package's scoped properties", -> + atom.activatePackage('ruby.tmbundle', sync: true) + atom.deactivatePackage('ruby.tmbundle') + expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined() describe ".getVersion(callback)", -> it "calls the callback with the current version number", -> diff --git a/spec/app/config-spec.coffee b/spec/app/config-spec.coffee index 39aae22fe..2daa360cd 100644 --- a/spec/app/config-spec.coffee +++ b/spec/app/config-spec.coffee @@ -1,5 +1,4 @@ -Config = require 'config' -fs = require 'fs' +fs = require 'fs-utils' describe "Config", -> describe ".get(keyPath) and .set(keyPath, value)", -> @@ -50,7 +49,7 @@ describe "Config", -> config.save() expect(fs.write.argsForCall[0][0]).toBe(fs.join(config.configDirPath, "config.cson")) - {CoffeeScript} = require 'coffee-script' + CoffeeScript = require 'coffee-script' writtenConfig = CoffeeScript.eval(fs.write.argsForCall[0][1], bare: true) expect(writtenConfig).toEqual config.settings @@ -151,4 +150,4 @@ describe "Config", -> config.loadUserConfig() config.set("hair", "blonde") # trigger a save expect(console.error).toHaveBeenCalled() - expect(config.save).not.toHaveBeenCalled() \ No newline at end of file + expect(config.save).not.toHaveBeenCalled() diff --git a/spec/app/directory-spec.coffee b/spec/app/directory-spec.coffee index d33341623..4bbd8ea02 100644 --- a/spec/app/directory-spec.coffee +++ b/spec/app/directory-spec.coffee @@ -1,11 +1,11 @@ Directory = require 'directory' -fs = require 'fs' +fs = require 'fs-utils' describe "Directory", -> directory = null beforeEach -> - directory = new Directory(require.resolve('fixtures')) + directory = new Directory(fs.resolveOnLoadPath('fixtures')) afterEach -> directory.off() @@ -14,7 +14,7 @@ describe "Directory", -> temporaryFilePath = null beforeEach -> - temporaryFilePath = fs.join(require.resolve('fixtures'), 'temporary') + temporaryFilePath = fs.join(fs.resolveOnLoadPath('fixtures'), 'temporary') fs.remove(temporaryFilePath) if fs.exists(temporaryFilePath) afterEach -> @@ -65,3 +65,11 @@ describe "Directory", -> waits 20 runs -> expect(changeHandler.callCount).toBe 0 + it "includes symlink information about entries", -> + entries = directory.getEntries() + for entry in entries + name = entry.getBaseName() + if name is 'symlink-to-dir' or name is 'symlink-to-file' + expect(entry.symlink).toBeTruthy() + else + expect(entry.symlink).toBeFalsy() diff --git a/spec/app/display-buffer-spec.coffee b/spec/app/display-buffer-spec.coffee index 2381d76e2..8227a94e2 100644 --- a/spec/app/display-buffer-spec.coffee +++ b/spec/app/display-buffer-spec.coffee @@ -1,11 +1,12 @@ DisplayBuffer = require 'display-buffer' -Buffer = require 'buffer' +Buffer = require 'text-buffer' _ = require 'underscore' describe "DisplayBuffer", -> [editSession, displayBuffer, buffer, changeHandler, tabLength] = [] beforeEach -> tabLength = 2 + atom.activatePackage('javascript.tmbundle', sync: true) editSession = project.buildEditSession('sample.js', { tabLength }) { buffer, displayBuffer } = editSession changeHandler = jasmine.createSpy 'changeHandler' diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index d9f7be7f6..3337d526b 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -1,5 +1,5 @@ Project = require 'project' -Buffer = require 'buffer' +Buffer = require 'text-buffer' EditSession = require 'edit-session' describe "EditSession", -> @@ -9,6 +9,7 @@ describe "EditSession", -> buffer.setText(buffer.getText().replace(/[ ]{2}/g, "\t")) beforeEach -> + atom.activatePackage('javascript.tmbundle', sync: true) editSession = project.buildEditSession('sample.js', autoIndent: false) buffer = editSession.buffer lineLengths = buffer.getLines().map (line) -> line.length @@ -395,6 +396,20 @@ describe "EditSession", -> buffer.insert([8, 0], '...') expect(cursorMovedHandler).not.toHaveBeenCalled() + describe "addCursorAtScreenPosition(screenPosition)", -> + describe "when a cursor already exists at the position", -> + it "returns the existing cursor", -> + cursor1 = editSession.addCursorAtScreenPosition([0,2]) + cursor2 = editSession.addCursorAtScreenPosition([0,2]) + expect(cursor2.marker).toBe cursor1.marker + + describe "addCursorAtBufferPosition(bufferPosition)", -> + describe "when a cursor already exists at the position", -> + it "returns the existing cursor", -> + cursor1 = editSession.addCursorAtBufferPosition([1,4]) + cursor2 = editSession.addCursorAtBufferPosition([1,4]) + expect(cursor2.marker).toBe cursor1.marker + describe "selection", -> selection = null @@ -1955,6 +1970,18 @@ describe "EditSession", -> expect(buffer.getLineCount()).toBe(1) expect(buffer.getText()).toBe('') + describe "when soft wrap is enabled", -> + it "deletes the entire line that the cursor is on", -> + editSession.setSoftWrapColumn(10) + editSession.setCursorBufferPosition([6]) + + line7 = buffer.lineForRow(7) + count = buffer.getLineCount() + expect(buffer.lineForRow(6)).not.toBe(line7) + editSession.deleteLine() + expect(buffer.lineForRow(6)).toBe(line7) + expect(buffer.getLineCount()).toBe(count - 1) + describe ".transpose()", -> it "swaps two characters", -> editSession.buffer.setText("abc") @@ -2036,13 +2063,14 @@ describe "EditSession", -> describe "when the 'grammars-loaded' event is triggered on the syntax global", -> it "reloads the edit session's grammar and re-tokenizes the buffer if it changes", -> editSession.destroy() - grammarToReturn = syntax.grammarByFileTypeSuffix('txt') - spyOn(syntax, 'grammarForFilePath').andCallFake -> grammarToReturn + jsGrammar = syntax.selectGrammar('a.js') + grammarToReturn = syntax.nullGrammar + spyOn(syntax, 'selectGrammar').andCallFake -> grammarToReturn editSession = project.buildEditSession('sample.js', autoIndent: false) expect(editSession.lineForScreenRow(0).tokens.length).toBe 1 - grammarToReturn = syntax.grammarByFileTypeSuffix('js') + grammarToReturn = jsGrammar syntax.trigger 'grammars-loaded' expect(editSession.lineForScreenRow(0).tokens.length).toBeGreaterThan 1 diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 04e6c9b57..885981485 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -1,17 +1,19 @@ EditSession = require 'edit-session' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Editor = require 'editor' Range = require 'range' Project = require 'project' $ = require 'jquery' {$$} = require 'space-pen' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' describe "Editor", -> [buffer, editor, editSession, cachedLineHeight, cachedCharWidth] = [] beforeEach -> + atom.activatePackage('text.tmbundle', sync: true) + atom.activatePackage('javascript.tmbundle', sync: true) editSession = project.buildEditSession('sample.js') buffer = editSession.buffer editor = new Editor(editSession) @@ -332,12 +334,6 @@ describe "Editor", -> expect(selectionRegion.height()).toBe editor.lineHeight expect(selectionRegion.width()).toBe 5 * editor.charWidth - it "updates the gutter width and font size", -> - editor.attachToDom() - config.set("editor.fontSize", 20) - expect(editor.gutter.css('font-size')).toBe "20px" - expect(editor.gutter.width()).toBe(editor.charWidth * 2 + editor.gutter.calculateLineNumberPadding()) - it "updates lines if there are unrendered lines", -> editor.attachToDom(heightInLines: 5) originalLineCount = editor.renderedLines.find(".line").length @@ -562,6 +558,20 @@ describe "Editor", -> expect(editor.scrollTop()).toBe 0 + it "ignores non left-click and drags", -> + editor.attachToDom() + editor.css(position: 'absolute', top: 10, left: 10) + + event = mousedownEvent(editor: editor, point: [4, 10]) + event.originalEvent.which = 2 + editor.renderedLines.trigger(event) + $(document).trigger mousemoveEvent(editor: editor, point: [5, 27]) + $(document).trigger 'mouseup' + + range = editor.getSelection().getScreenRange() + expect(range.start).toEqual({row: 4, column: 10}) + expect(range.end).toEqual({row: 4, column: 10}) + describe "double-click and drag", -> it "selects the word under the cursor, then continues to select by word in either direction as the mouse is dragged", -> expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0) @@ -981,6 +991,15 @@ describe "Editor", -> editor.setCursorScreenPosition([2, 5]) expect(editor.scrollView.scrollLeft()).toBe 0 + describe "when editor:toggle-soft-wrap is toggled", -> + describe "when the text exceeds the editor width and the scroll-view is horizontally scrolled", -> + it "wraps the text and renders properly", -> + editor.attachToDom(heightInLines: 30, widthInChars: 30) + editor.setText("Fashion axe umami jean shorts retro hashtag carles mumblecore. Photo booth skateboard Austin gentrify occupy ethical. Food truck gastropub keffiyeh, squid deep v pinterest literally sustainable salvia scenester messenger bag. Neutra messenger bag flexitarian four loko, shoreditch VHS pop-up tumblr seitan synth master cleanse. Marfa selvage ugh, raw denim authentic try-hard mcsweeney's trust fund fashion axe actually polaroid viral sriracha. Banh mi marfa plaid single-origin coffee. Pickled mumblecore lomo ugh bespoke.") + editor.scrollView.scrollLeft(editor.charWidth * 30) + editor.trigger "editor:toggle-soft-wrap" + expect(editor.scrollView.scrollLeft()).toBe 0 + describe "text rendering", -> describe "when all lines in the buffer are visible on screen", -> beforeEach -> @@ -1054,90 +1073,6 @@ describe "Editor", -> buffer.insert([1,0], "/*") expect(editor.renderedLines.find('.line:eq(2) > span:first > span:first')).toMatchSelector '.comment' - describe "when soft-wrap is enabled", -> - beforeEach -> - setEditorHeightInLines(editor, 20) - setEditorWidthInChars(editor, 50) - editor.setSoftWrap(true) - expect(editor.activeEditSession.softWrapColumn).toBe 50 - - it "wraps lines that are too long to fit within the editor's width, adjusting cursor positioning accordingly", -> - expect(editor.renderedLines.find('.line').length).toBe 16 - expect(editor.renderedLines.find('.line:eq(3)').text()).toBe " var pivot = items.shift(), current, left = [], " - expect(editor.renderedLines.find('.line:eq(4)').text()).toBe "right = [];" - - editor.setCursorBufferPosition([3, 51], wrapAtSoftNewlines: true) - expect(editor.find('.cursor').offset()).toEqual(editor.renderedLines.find('.line:eq(4)').offset()) - - editor.setCursorBufferPosition([4, 0]) - expect(editor.find('.cursor').offset()).toEqual(editor.renderedLines.find('.line:eq(5)').offset()) - - editor.getSelection().setBufferRange(new Range([6, 30], [6, 55])) - [region1, region2] = editor.getSelectionView().regions - expect(region1.offset().top).toBeCloseTo(editor.renderedLines.find('.line:eq(7)').offset().top) - expect(region2.offset().top).toBeCloseTo(editor.renderedLines.find('.line:eq(8)').offset().top) - - it "handles changes to wrapped lines correctly", -> - buffer.insert([6, 28], '1234567') - expect(editor.renderedLines.find('.line:eq(7)').text()).toBe ' current < pivot ? left1234567.push(current) ' - expect(editor.renderedLines.find('.line:eq(8)').text()).toBe ': right.push(current);' - expect(editor.renderedLines.find('.line:eq(9)').text()).toBe ' }' - - it "changes the max line length and repositions the cursor when the window size changes", -> - editor.setCursorBufferPosition([3, 60]) - setEditorWidthInChars(editor, 40) - expect(editor.renderedLines.find('.line').length).toBe 19 - expect(editor.renderedLines.find('.line:eq(4)').text()).toBe "left = [], right = [];" - expect(editor.renderedLines.find('.line:eq(5)').text()).toBe " while(items.length > 0) {" - expect(editor.bufferPositionForScreenPosition(editor.getCursorScreenPosition())).toEqual [3, 60] - - it "does not wrap the lines of any newly assigned buffers", -> - otherEditSession = project.buildEditSession() - otherEditSession.buffer.setText([1..100].join('')) - editor.edit(otherEditSession) - expect(editor.renderedLines.find('.line').length).toBe(1) - - it "unwraps lines and cancels window resize listener when softwrap is disabled", -> - editor.toggleSoftWrap() - expect(editor.renderedLines.find('.line:eq(3)').text()).toBe ' var pivot = items.shift(), current, left = [], right = [];' - - spyOn(editor, 'setSoftWrapColumn') - $(window).trigger 'resize' - expect(editor.setSoftWrapColumn).not.toHaveBeenCalled() - - it "allows the cursor to move down to the last line", -> - _.times editor.getLastScreenRow(), -> editor.moveCursorDown() - expect(editor.getCursorScreenPosition()).toEqual [editor.getLastScreenRow(), 0] - editor.moveCursorDown() - expect(editor.getCursorScreenPosition()).toEqual [editor.getLastScreenRow(), 2] - - it "allows the cursor to move up to a shorter soft wrapped line", -> - editor.setCursorScreenPosition([11, 15]) - editor.moveCursorUp() - expect(editor.getCursorScreenPosition()).toEqual [10, 10] - editor.moveCursorUp() - editor.moveCursorUp() - expect(editor.getCursorScreenPosition()).toEqual [8, 15] - - it "it allows the cursor to wrap when moving horizontally past the beginning / end of a wrapped line", -> - editor.setCursorScreenPosition([11, 0]) - editor.moveCursorLeft() - expect(editor.getCursorScreenPosition()).toEqual [10, 10] - - editor.moveCursorRight() - expect(editor.getCursorScreenPosition()).toEqual [11, 0] - - it "calls .setSoftWrapColumn() when the editor is attached because now its dimensions are available to calculate it", -> - otherEditor = new Editor(editSession: project.buildEditSession('sample.js')) - spyOn(otherEditor, 'setSoftWrapColumn') - - otherEditor.setSoftWrap(true) - expect(otherEditor.setSoftWrapColumn).not.toHaveBeenCalled() - - otherEditor.simulateDomAttachment() - expect(otherEditor.setSoftWrapColumn).toHaveBeenCalled() - otherEditor.remove() - describe "when some lines at the end of the buffer are not visible on screen", -> beforeEach -> editor.attachToDom(heightInLines: 5.5) @@ -1184,7 +1119,7 @@ describe "Editor", -> expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(7) expect(editor.gutter.find('.line-number').length).toBe 8 - expect(editor.gutter.find('.line-number:last').text()).toBe '8' + expect(editor.gutter.find('.line-number:last').intValue()).toBe 8 editor.scrollTop(4 * editor.lineHeight) expect(editor.renderedLines.find('.line').length).toBe 10 @@ -1221,16 +1156,16 @@ describe "Editor", -> expect(editor.renderedLines.find('.line').length).toBe 10 expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(1) expect(editor.renderedLines.find('.line:last').html()).toBe ' ' # line 10 is blank - expect(editor.gutter.find('.line-number:first').text()).toBe '2' - expect(editor.gutter.find('.line-number:last').text()).toBe '11' + expect(editor.gutter.find('.line-number:first').intValue()).toBe 2 + expect(editor.gutter.find('.line-number:last').intValue()).toBe 11 # here we don't scroll far enough to trigger additional rendering editor.scrollTop(editor.lineHeight * 5.5) # first visible row will be 5, last will be 10 expect(editor.renderedLines.find('.line').length).toBe 10 expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(1) expect(editor.renderedLines.find('.line:last').html()).toBe ' ' # line 10 is blank - expect(editor.gutter.find('.line-number:first').text()).toBe '2' - expect(editor.gutter.find('.line-number:last').text()).toBe '11' + expect(editor.gutter.find('.line-number:first').intValue()).toBe 2 + expect(editor.gutter.find('.line-number:last').intValue()).toBe 11 editor.scrollTop(editor.lineHeight * 7.5) # first visible row is 7, last will be 12 expect(editor.renderedLines.find('.line').length).toBe 8 @@ -1586,74 +1521,143 @@ describe "Editor", -> expect(editor.renderedLines.find('.line:eq(10) .indent-guide').length).toBe 2 expect(editor.renderedLines.find('.line:eq(10) .indent-guide').text()).toBe ' ' + describe "when soft-wrap is enabled", -> + beforeEach -> + editor.attachToDom() + setEditorHeightInLines(editor, 20) + setEditorWidthInChars(editor, 50) + editor.setSoftWrap(true) + expect(editor.activeEditSession.softWrapColumn).toBe 50 + + it "wraps lines that are too long to fit within the editor's width, adjusting cursor positioning accordingly", -> + expect(editor.renderedLines.find('.line').length).toBe 16 + expect(editor.renderedLines.find('.line:eq(3)').text()).toBe " var pivot = items.shift(), current, left = [], " + expect(editor.renderedLines.find('.line:eq(4)').text()).toBe "right = [];" + + editor.setCursorBufferPosition([3, 51], wrapAtSoftNewlines: true) + expect(editor.find('.cursor').offset()).toEqual(editor.renderedLines.find('.line:eq(4)').offset()) + + editor.setCursorBufferPosition([4, 0]) + expect(editor.find('.cursor').offset()).toEqual(editor.renderedLines.find('.line:eq(5)').offset()) + + editor.getSelection().setBufferRange(new Range([6, 30], [6, 55])) + [region1, region2] = editor.getSelectionView().regions + expect(region1.offset().top).toBeCloseTo(editor.renderedLines.find('.line:eq(7)').offset().top) + expect(region2.offset().top).toBeCloseTo(editor.renderedLines.find('.line:eq(8)').offset().top) + + it "handles changes to wrapped lines correctly", -> + buffer.insert([6, 28], '1234567') + expect(editor.renderedLines.find('.line:eq(7)').text()).toBe ' current < pivot ? left1234567.push(current) ' + expect(editor.renderedLines.find('.line:eq(8)').text()).toBe ': right.push(current);' + expect(editor.renderedLines.find('.line:eq(9)').text()).toBe ' }' + + it "changes the max line length and repositions the cursor when the window size changes", -> + editor.setCursorBufferPosition([3, 60]) + setEditorWidthInChars(editor, 40) + expect(editor.renderedLines.find('.line').length).toBe 19 + expect(editor.renderedLines.find('.line:eq(4)').text()).toBe "left = [], right = [];" + expect(editor.renderedLines.find('.line:eq(5)').text()).toBe " while(items.length > 0) {" + expect(editor.bufferPositionForScreenPosition(editor.getCursorScreenPosition())).toEqual [3, 60] + + it "does not wrap the lines of any newly assigned buffers", -> + otherEditSession = project.buildEditSession() + otherEditSession.buffer.setText([1..100].join('')) + editor.edit(otherEditSession) + expect(editor.renderedLines.find('.line').length).toBe(1) + + it "unwraps lines and cancels window resize listener when softwrap is disabled", -> + editor.toggleSoftWrap() + expect(editor.renderedLines.find('.line:eq(3)').text()).toBe ' var pivot = items.shift(), current, left = [], right = [];' + + spyOn(editor, 'setSoftWrapColumn') + $(window).trigger 'resize' + expect(editor.setSoftWrapColumn).not.toHaveBeenCalled() + + it "allows the cursor to move down to the last line", -> + _.times editor.getLastScreenRow(), -> editor.moveCursorDown() + expect(editor.getCursorScreenPosition()).toEqual [editor.getLastScreenRow(), 0] + editor.moveCursorDown() + expect(editor.getCursorScreenPosition()).toEqual [editor.getLastScreenRow(), 2] + + it "allows the cursor to move up to a shorter soft wrapped line", -> + editor.setCursorScreenPosition([11, 15]) + editor.moveCursorUp() + expect(editor.getCursorScreenPosition()).toEqual [10, 10] + editor.moveCursorUp() + editor.moveCursorUp() + expect(editor.getCursorScreenPosition()).toEqual [8, 15] + + it "it allows the cursor to wrap when moving horizontally past the beginning / end of a wrapped line", -> + editor.setCursorScreenPosition([11, 0]) + editor.moveCursorLeft() + expect(editor.getCursorScreenPosition()).toEqual [10, 10] + + editor.moveCursorRight() + expect(editor.getCursorScreenPosition()).toEqual [11, 0] + + it "calls .setSoftWrapColumn() when the editor is attached because now its dimensions are available to calculate it", -> + otherEditor = new Editor(editSession: project.buildEditSession('sample.js')) + spyOn(otherEditor, 'setSoftWrapColumn') + + otherEditor.setSoftWrap(true) + expect(otherEditor.setSoftWrapColumn).not.toHaveBeenCalled() + + otherEditor.simulateDomAttachment() + expect(otherEditor.setSoftWrapColumn).toHaveBeenCalled() + otherEditor.remove() + describe "gutter rendering", -> beforeEach -> editor.attachToDom(heightInLines: 5.5) - it "creates a line number element for each visible line, plus overdraw", -> + it "creates a line number element for each visible line with   padding to the left of the number", -> expect(editor.gutter.find('.line-number').length).toBe 8 - expect(editor.find('.line-number:first').text()).toBe "1" - expect(editor.gutter.find('.line-number:last').text()).toBe "8" + expect(editor.find('.line-number:first').html()).toBe " 1" + expect(editor.gutter.find('.line-number:last').html()).toBe " 8" # here we don't scroll far enough to trigger additional rendering editor.scrollTop(editor.lineHeight * 1.5) expect(editor.renderedLines.find('.line').length).toBe 8 - expect(editor.gutter.find('.line-number:first').text()).toBe "1" - expect(editor.gutter.find('.line-number:last').text()).toBe "8" + expect(editor.gutter.find('.line-number:first').html()).toBe " 1" + expect(editor.gutter.find('.line-number:last').html()).toBe " 8" editor.scrollTop(editor.lineHeight * 3.5) expect(editor.renderedLines.find('.line').length).toBe 10 - expect(editor.gutter.find('.line-number:first').text()).toBe "2" - expect(editor.gutter.find('.line-number:last').text()).toBe "11" - - describe "width", -> - it "sets the width based on largest line number", -> - expect(editor.gutter.lineNumbers.outerWidth()).toBe(editor.charWidth * 2 + editor.gutter.calculateLineNumberPadding()) - - it "updates the width and the left position of the scroll view when total number of lines gains a digit", -> - editor.setText("") - - expect(editor.gutter.lineNumbers.outerWidth()).toBe(editor.charWidth * 1 + editor.gutter.calculateLineNumberPadding()) - expect(parseInt(editor.scrollView.css('left'))).toBe editor.gutter.outerWidth() - - for i in [1..9] # Ends on an empty line 10 - editor.insertText "#{i}\n" - - expect(editor.gutter.lineNumbers.outerWidth()).toBe(editor.charWidth * 2 + editor.gutter.calculateLineNumberPadding()) - expect(parseInt(editor.scrollView.css('left'))).toBe editor.gutter.outerWidth() + expect(editor.gutter.find('.line-number:first').html()).toBe " 2" + expect(editor.gutter.find('.line-number:last').html()).toBe "11" describe "when lines are inserted", -> it "re-renders the correct line number range in the gutter", -> editor.scrollTop(3 * editor.lineHeight) - expect(editor.gutter.find('.line-number:first').text()).toBe '2' - expect(editor.gutter.find('.line-number:last').text()).toBe '11' + expect(editor.gutter.find('.line-number:first').intValue()).toBe 2 + expect(editor.gutter.find('.line-number:last').intValue()).toBe 11 buffer.insert([6, 0], '\n') - expect(editor.gutter.find('.line-number:first').text()).toBe '2' - expect(editor.gutter.find('.line-number:last').text()).toBe '11' + expect(editor.gutter.find('.line-number:first').intValue()).toBe 2 + expect(editor.gutter.find('.line-number:last').intValue()).toBe 11 describe "when wrapping is on", -> it "renders a • instead of line number for wrapped portions of lines", -> editor.setSoftWrapColumn(50) expect(editor.gutter.find('.line-number').length).toEqual(8) - expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' - expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '•' - expect(editor.gutter.find('.line-number:eq(5)').text()).toBe '5' + expect(editor.gutter.find('.line-number:eq(3)').intValue()).toBe 4 + expect(editor.gutter.find('.line-number:eq(4)').html()).toBe ' •' + expect(editor.gutter.find('.line-number:eq(5)').intValue()).toBe 5 describe "when there are folds", -> it "skips line numbers covered by the fold and updates them when the fold changes", -> editor.createFold(3, 5) - expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' - expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '7' + expect(editor.gutter.find('.line-number:eq(3)').intValue()).toBe 4 + expect(editor.gutter.find('.line-number:eq(4)').intValue()).toBe 7 buffer.insert([4,0], "\n\n") - expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' - expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '9' + expect(editor.gutter.find('.line-number:eq(3)').intValue()).toBe 4 + expect(editor.gutter.find('.line-number:eq(4)').intValue()).toBe 9 buffer.delete([[3,0], [6,0]]) - expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' - expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '6' + expect(editor.gutter.find('.line-number:eq(3)').intValue()).toBe 4 + expect(editor.gutter.find('.line-number:eq(4)').intValue()).toBe 6 it "redraws gutter numbers when lines are unfolded", -> setEditorHeightInLines(editor, 20) @@ -1666,7 +1670,7 @@ describe "Editor", -> it "styles folded line numbers", -> editor.createFold(3, 5) expect(editor.gutter.find('.line-number.fold').length).toBe 1 - expect(editor.gutter.find('.line-number.fold:eq(0)').text()).toBe '4' + expect(editor.gutter.find('.line-number.fold:eq(0)').intValue()).toBe 4 describe "when the scrollView is scrolled to the right", -> it "adds a drop shadow to the gutter", -> @@ -1691,8 +1695,8 @@ describe "Editor", -> expect(editor.gutter.lineNumbers.css('padding-top')).toBe "#{editor.lineHeight * 1}px" expect(editor.gutter.lineNumbers.css('padding-bottom')).toBe "#{editor.lineHeight * 2}px" expect(editor.renderedLines.find('.line').length).toBe 10 - expect(editor.gutter.find('.line-number:first').text()).toBe "2" - expect(editor.gutter.find('.line-number:last').text()).toBe "11" + expect(editor.gutter.find('.line-number:first').intValue()).toBe 2 + expect(editor.gutter.find('.line-number:last').intValue()).toBe 11 describe "when the switching from an edit session for a long buffer to an edit session for a short buffer", -> it "updates the line numbers to reflect the shorter buffer", -> @@ -1707,11 +1711,10 @@ describe "Editor", -> expect(editor.gutter.lineNumbers.find('.line-number').length).toBe 1 describe "when the editor is mini", -> - it "hides the gutter and does not change the scroll view's left position", -> + it "hides the gutter", -> miniEditor = new Editor(mini: true) miniEditor.attachToDom() expect(miniEditor.gutter).toBeHidden() - expect(miniEditor.scrollView.css('left')).toBe '0px' it "doesn't highlight the only line", -> miniEditor = new Editor(mini: true) @@ -1730,6 +1733,24 @@ describe "Editor", -> miniEditor.setText(" a line with tabs\tand spaces ") expect(miniEditor.renderedLines.find('.line').text()).toBe "#{space}a line with tabs#{tab} and spaces#{space}" + it "lets you set the grammar", -> + miniEditor = new Editor(mini: true) + miniEditor.setText("var something") + previousTokens = miniEditor.lineForScreenRow(0).tokens + miniEditor.setGrammar(syntax.selectGrammar('something.js')) + expect(miniEditor.getGrammar().name).toBe "JavaScript" + expect(previousTokens).not.toEqual miniEditor.lineForScreenRow(0).tokens + + # doesn't allow regular editors to set grammars + expect(-> editor.setGrammar()).toThrow() + + + describe "when config.editor.showLineNumbers is false", -> + it "doesn't render any line numbers", -> + expect(editor.gutter.lineNumbers).toBeVisible() + config.set("editor.showLineNumbers", false) + expect(editor.gutter.lineNumbers).not.toBeVisible() + describe "gutter line highlighting", -> beforeEach -> editor.attachToDom(heightInLines: 5.5) @@ -1738,13 +1759,13 @@ describe "Editor", -> it "highlights the line where the initial cursor position is", -> expect(editor.getCursorBufferPosition().row).toBe 0 expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 - expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "1" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').intValue()).toBe 1 it "updates the highlighted line when the cursor position changes", -> editor.setCursorBufferPosition([1,0]) expect(editor.getCursorBufferPosition().row).toBe 1 expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 - expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "2" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').intValue()).toBe 2 describe "when there is wrapping", -> beforeEach -> @@ -1755,13 +1776,13 @@ describe "Editor", -> it "highlights the line where the initial cursor position is", -> expect(editor.getCursorBufferPosition().row).toBe 0 expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 - expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "1" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').intValue()).toBe 1 it "updates the highlighted line when the cursor position changes", -> editor.setCursorBufferPosition([1,0]) expect(editor.getCursorBufferPosition().row).toBe 1 expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 - expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "2" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').intValue()).toBe 2 describe "when the selection spans multiple lines", -> beforeEach -> @@ -1781,13 +1802,13 @@ describe "Editor", -> editor.getSelection().setBufferRange(new Range([0,0],[1,0])) expect(editor.getSelection().isSingleScreenLine()).toBe false expect(editor.find('.line-number.cursor-line').length).toBe 1 - expect(editor.find('.line-number.cursor-line').text()).toBe "1" + expect(editor.find('.line-number.cursor-line').intValue()).toBe 1 it "when a newline is deleted with backspace, the line number of the new cursor position is highlighted", -> editor.setCursorScreenPosition([1,0]) editor.backspace() expect(editor.find('.line-number.cursor-line').length).toBe 1 - expect(editor.find('.line-number.cursor-line').text()).toBe "1" + expect(editor.find('.line-number.cursor-line').intValue()).toBe 1 describe "line highlighting", -> beforeEach -> @@ -2051,7 +2072,7 @@ describe "Editor", -> [path] = [] beforeEach -> - path = "/tmp/grammar-change.txt" + path = fs.join(fs.absolute("/tmp"), "grammar-change.txt") fs.write(path, "var i;") afterEach -> @@ -2059,14 +2080,10 @@ describe "Editor", -> it "updates all the rendered lines when the grammar changes", -> editor.edit(project.buildEditSession(path)) - expect(editor.getGrammar().name).toBe 'Plain Text' - jsGrammar = syntax.grammarForFilePath('/tmp/js.js') - expect(jsGrammar.name).toBe 'JavaScript' - - project.addGrammarOverrideForPath(path, jsGrammar) + syntax.setGrammarOverrideForPath(path, 'source.js') expect(editor.reloadGrammar()).toBeTruthy() - expect(editor.getGrammar()).toBe jsGrammar + expect(editor.getGrammar().name).toBe 'JavaScript' tokenizedBuffer = editor.activeEditSession.displayBuffer.tokenizedBuffer line0 = tokenizedBuffer.lineForScreenRow(0) @@ -2090,10 +2107,8 @@ describe "Editor", -> expect(eventHandler).not.toHaveBeenCalled() - jsGrammar = syntax.grammarForFilePath('/tmp/js.js') - project.addGrammarOverrideForPath(path, jsGrammar) + syntax.setGrammarOverrideForPath(path, 'source.js') editor.reloadGrammar() - expect(eventHandler).toHaveBeenCalled() describe ".replaceSelectedText()", -> diff --git a/spec/app/event-emitter-spec.coffee b/spec/app/event-emitter-spec.coffee index dd02fdaa3..5256220ee 100644 --- a/spec/app/event-emitter-spec.coffee +++ b/spec/app/event-emitter-spec.coffee @@ -167,5 +167,3 @@ describe "EventEmitter mixin", -> object.off 'foo' expect(object.subscriptionCount()).toBe 2 - - diff --git a/spec/app/file-spec.coffee b/spec/app/file-spec.coffee index d99bd4380..21f57833f 100644 --- a/spec/app/file-spec.coffee +++ b/spec/app/file-spec.coffee @@ -1,11 +1,11 @@ File = require 'file' -fs = require 'fs' +fs = require 'fs-utils' describe 'File', -> [path, file] = [] beforeEach -> - path = fs.join(require.resolve('fixtures'), "atom-file-test.txt") # Don't put in /tmp because /tmp symlinks to /private/tmp and screws up the rename test + path = fs.join(fs.resolveOnLoadPath('fixtures'), "atom-file-test.txt") # Don't put in /tmp because /tmp symlinks to /private/tmp and screws up the rename test fs.remove(path) if fs.exists(path) fs.write(path, "this is old!") file = new File(path) diff --git a/spec/app/git-spec.coffee b/spec/app/git-spec.coffee index fcdb120d8..921d88cc5 100644 --- a/spec/app/git-spec.coffee +++ b/spec/app/git-spec.coffee @@ -1,5 +1,5 @@ Git = require 'git' -fs = require 'fs' +fs = require 'fs-utils' Task = require 'task' describe "Git", -> @@ -21,39 +21,39 @@ describe "Git", -> describe ".getPath()", -> it "returns the repository path for a .git directory path", -> - repo = new Git(require.resolve('fixtures/git/master.git/HEAD')) - expect(repo.getPath()).toBe require.resolve('fixtures/git/master.git') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/master.git/HEAD')) + expect(repo.getPath()).toBe fs.resolveOnLoadPath('fixtures/git/master.git') it "returns the repository path for a repository path", -> - repo = new Git(require.resolve('fixtures/git/master.git')) - expect(repo.getPath()).toBe require.resolve('fixtures/git/master.git') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/master.git')) + expect(repo.getPath()).toBe fs.resolveOnLoadPath('fixtures/git/master.git') describe ".getHead()", -> it "returns a branch name for a non-empty repository", -> - repo = new Git(require.resolve('fixtures/git/master.git')) + repo = new Git(fs.resolveOnLoadPath('fixtures/git/master.git')) expect(repo.getHead()).toBe 'refs/heads/master' describe ".getShortHead()", -> it "returns a branch name for a non-empty repository", -> - repo = new Git(require.resolve('fixtures/git/master.git')) + repo = new Git(fs.resolveOnLoadPath('fixtures/git/master.git')) expect(repo.getShortHead()).toBe 'master' describe ".isPathIgnored(path)", -> it "returns true for an ignored path", -> - repo = new Git(require.resolve('fixtures/git/ignore.git')) + repo = new Git(fs.resolveOnLoadPath('fixtures/git/ignore.git')) expect(repo.isPathIgnored('a.txt')).toBeTruthy() it "returns false for a non-ignored path", -> - repo = new Git(require.resolve('fixtures/git/ignore.git')) + repo = new Git(fs.resolveOnLoadPath('fixtures/git/ignore.git')) expect(repo.isPathIgnored('b.txt')).toBeFalsy() describe ".isPathModified(path)", -> [repo, path, newPath, originalPathText] = [] beforeEach -> - repo = new Git(require.resolve('fixtures/git/working-dir')) - path = require.resolve('fixtures/git/working-dir/file.txt') - newPath = fs.join(require.resolve('fixtures/git/working-dir'), 'new-path.txt') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/working-dir')) + path = fs.resolveOnLoadPath('fixtures/git/working-dir/file.txt') + newPath = fs.join(fs.resolveOnLoadPath('fixtures/git/working-dir'), 'new-path.txt') originalPathText = fs.read(path) afterEach -> @@ -79,9 +79,9 @@ describe "Git", -> [path, newPath] = [] beforeEach -> - repo = new Git(require.resolve('fixtures/git/working-dir')) - path = require.resolve('fixtures/git/working-dir/file.txt') - newPath = fs.join(require.resolve('fixtures/git/working-dir'), 'new-path.txt') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/working-dir')) + path = fs.resolveOnLoadPath('fixtures/git/working-dir/file.txt') + newPath = fs.join(fs.resolveOnLoadPath('fixtures/git/working-dir'), 'new-path.txt') fs.write(newPath, "i'm new here") afterEach -> @@ -98,10 +98,10 @@ describe "Git", -> [path1, path2, originalPath1Text, originalPath2Text] = [] beforeEach -> - repo = new Git(require.resolve('fixtures/git/working-dir')) - path1 = require.resolve('fixtures/git/working-dir/file.txt') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/working-dir')) + path1 = fs.resolveOnLoadPath('fixtures/git/working-dir/file.txt') originalPath1Text = fs.read(path1) - path2 = require.resolve('fixtures/git/working-dir/other.txt') + path2 = fs.resolveOnLoadPath('fixtures/git/working-dir/other.txt') originalPath2Text = fs.read(path2) afterEach -> @@ -141,7 +141,7 @@ describe "Git", -> describe ".destroy()", -> it "throws an exception when any method is called after it is called", -> - repo = new Git(require.resolve('fixtures/git/master.git/HEAD')) + repo = new Git(fs.resolveOnLoadPath('fixtures/git/master.git/HEAD')) repo.destroy() expect(-> repo.getHead()).toThrow() @@ -149,8 +149,8 @@ describe "Git", -> [path, originalPathText] = [] beforeEach -> - repo = new Git(require.resolve('fixtures/git/working-dir')) - path = require.resolve('fixtures/git/working-dir/file.txt') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/working-dir')) + path = fs.resolveOnLoadPath('fixtures/git/working-dir/file.txt') originalPathText = fs.read(path) afterEach -> @@ -165,8 +165,8 @@ describe "Git", -> [path, originalPathText] = [] beforeEach -> - repo = new Git(require.resolve('fixtures/git/working-dir')) - path = require.resolve('fixtures/git/working-dir/file.txt') + repo = new Git(fs.resolveOnLoadPath('fixtures/git/working-dir')) + path = fs.resolveOnLoadPath('fixtures/git/working-dir/file.txt') originalPathText = fs.read(path) afterEach -> @@ -188,7 +188,7 @@ describe "Git", -> [newPath, modifiedPath, cleanPath, originalModifiedPathText] = [] beforeEach -> - repo = new Git(require.resolve('fixtures/git/working-dir')) + repo = new Git(fs.resolveOnLoadPath('fixtures/git/working-dir')) modifiedPath = project.resolve('git/working-dir/file.txt') originalModifiedPathText = fs.read(modifiedPath) newPath = project.resolve('git/working-dir/untracked.txt') diff --git a/spec/app/keymap-spec.coffee b/spec/app/keymap-spec.coffee index b813ad50c..2e6e7a534 100644 --- a/spec/app/keymap-spec.coffee +++ b/spec/app/keymap-spec.coffee @@ -1,5 +1,6 @@ Keymap = require 'keymap' $ = require 'jquery' +{$$} = require 'space-pen' RootView = require 'root-view' describe "Keymap", -> @@ -234,7 +235,7 @@ describe "Keymap", -> it "returns false to prevent the browser from transferring focus", -> expect(keymap.handleKeyEvent(keydownEvent('U+0009', target: fragment[0]))).toBe false - describe ".bindKeys(selector, hash)", -> + describe ".bindKeys(selector, bindings)", -> it "normalizes the key patterns in the hash to put the modifiers in alphabetical order", -> fooHandler = jasmine.createSpy('fooHandler') fragment.on 'foo', fooHandler @@ -249,6 +250,24 @@ describe "Keymap", -> expect(result).toBe(false) expect(fooHandler).toHaveBeenCalled() + describe ".remove(name)", -> + it "removes the binding set with the given selector and bindings", -> + keymap.add 'nature', + '.green': + 'ctrl-c': 'cultivate' + '.brown': + 'ctrl-h': 'harvest' + + expect(keymap.bindingsForElement($$ -> @div class: 'green')).toEqual { 'ctrl-c': 'cultivate' } + expect(keymap.bindingsForElement($$ -> @div class: 'brown')).toEqual { 'ctrl-h': 'harvest' } + + keymap.remove('nature') + + expect(keymap.bindingsForElement($$ -> @div class: 'green')).toEqual {} + expect(keymap.bindingsForElement($$ -> @div class: 'brown')).toEqual {} + expect(keymap.bindingSetsByFirstKeystroke['ctrl-c']).toEqual [] + expect(keymap.bindingSetsByFirstKeystroke['ctrl-h']).toEqual [] + describe ".keystrokeStringForEvent(event)", -> describe "when no modifiers are pressed", -> it "returns a string that identifies the key pressed", -> diff --git a/spec/app/language-mode-spec.coffee b/spec/app/language-mode-spec.coffee index 5b2704947..4244d3c72 100644 --- a/spec/app/language-mode-spec.coffee +++ b/spec/app/language-mode-spec.coffee @@ -1,5 +1,5 @@ Project = require 'project' -Buffer = require 'buffer' +Buffer = require 'text-buffer' EditSession = require 'edit-session' describe "LanguageMode", -> @@ -10,6 +10,7 @@ describe "LanguageMode", -> describe "common behavior", -> beforeEach -> + atom.activatePackage('javascript.tmbundle', sync: true) editSession = project.buildEditSession('sample.js', autoIndent: false) { buffer, languageMode } = editSession @@ -21,6 +22,7 @@ describe "LanguageMode", -> describe "javascript", -> beforeEach -> + atom.activatePackage('javascript.tmbundle', sync: true) editSession = project.buildEditSession('sample.js', autoIndent: false) { buffer, languageMode } = editSession @@ -60,9 +62,9 @@ describe "LanguageMode", -> expect(languageMode.suggestedIndentForBufferRow(2)).toBe 2 expect(languageMode.suggestedIndentForBufferRow(9)).toBe 1 - describe "coffeescript", -> beforeEach -> + atom.activatePackage('coffee-script-tmbundle', sync: true) editSession = project.buildEditSession('coffee.coffee', autoIndent: false) { buffer, languageMode } = editSession @@ -98,6 +100,7 @@ describe "LanguageMode", -> describe "css", -> beforeEach -> + atom.activatePackage('css.tmbundle', sync: true) editSession = project.buildEditSession('css.css', autoIndent: false) { buffer, languageMode } = editSession diff --git a/spec/app/native-spec.coffee b/spec/app/native-spec.coffee deleted file mode 100644 index 14302fce8..000000000 --- a/spec/app/native-spec.coffee +++ /dev/null @@ -1,6 +0,0 @@ -describe 'Native', -> - describe '$native.getPlatform()', -> - it 'returns a non-empty value', -> - platform = $native.getPlatform() - expect(platform).not.toBe '' - expect(platform.length).toBeGreaterThan(0) diff --git a/spec/app/pane-spec.coffee b/spec/app/pane-spec.coffee index 96f379acd..b67b41449 100644 --- a/spec/app/pane-spec.coffee +++ b/spec/app/pane-spec.coffee @@ -558,7 +558,7 @@ describe "Pane", -> expect(row2.height()).toBe 2/3 * container.height() expect(pane2.outerWidth()).toBe column1.outerWidth() expect(pane2.outerHeight()).toBe 1/3 * container.height() - expect(pane2.position().top).toBe row2.height() + expect(Math.round(pane2.position().top)).toBe row2.height() expect(row2.children().length).toBe 2 column3 = row2.children(':eq(0)').view() @@ -576,7 +576,7 @@ describe "Pane", -> expect(pane4.outerWidth()).toBe column3.width() expect(pane4.outerHeight()).toBe 1/3 * container.height() expect(pane5.outerWidth()).toBe column3.width() - expect(pane5.position().top).toBe pane4.outerHeight() + expect(Math.round(pane5.position().top)).toBe pane4.outerHeight() expect(pane5.outerHeight()).toBe 1/3 * container.height() pane5.remove() diff --git a/spec/app/project-spec.coffee b/spec/app/project-spec.coffee index 136e61a85..48f483fc5 100644 --- a/spec/app/project-spec.coffee +++ b/spec/app/project-spec.coffee @@ -1,6 +1,7 @@ Project = require 'project' -fs = require 'fs' +fs = require 'fs-utils' _ = require 'underscore' +BufferedProcess = require 'buffered-process' describe "Project", -> beforeEach -> @@ -33,7 +34,7 @@ describe "Project", -> describe ".buildEditSession(path)", -> [absolutePath, newBufferHandler, newEditSessionHandler] = [] beforeEach -> - absolutePath = require.resolve('fixtures/dir/a') + absolutePath = fs.resolveOnLoadPath('fixtures/dir/a') newBufferHandler = jasmine.createSpy('newBufferHandler') project.on 'buffer-created', newBufferHandler newEditSessionHandler = jasmine.createSpy('newEditSessionHandler') @@ -85,14 +86,14 @@ describe "Project", -> describe ".resolve(path)", -> it "returns an absolute path based on the project's root", -> - absolutePath = require.resolve('fixtures/dir/a') + absolutePath = fs.resolveOnLoadPath('fixtures/dir/a') expect(project.resolve('a')).toBe absolutePath expect(project.resolve(absolutePath + '/../a')).toBe absolutePath expect(project.resolve('a/../a')).toBe absolutePath describe ".relativize(path)", -> it "returns an relative path based on the project's root", -> - absolutePath = require.resolve('fixtures/dir') + absolutePath = fs.resolveOnLoadPath('fixtures/dir') expect(project.relativize(fs.join(absolutePath, "b"))).toBe "b" expect(project.relativize(fs.join(absolutePath, "b/file.coffee"))).toBe "b/file.coffee" expect(project.relativize(fs.join(absolutePath, "file.coffee"))).toBe "file.coffee" @@ -100,15 +101,15 @@ describe "Project", -> describe ".setPath(path)", -> describe "when path is a file", -> it "sets its path to the files parent directory and updates the root directory", -> - project.setPath(require.resolve('fixtures/dir/a')) - expect(project.getPath()).toEqual require.resolve('fixtures/dir') - expect(project.getRootDirectory().path).toEqual require.resolve('fixtures/dir') + project.setPath(fs.resolveOnLoadPath('fixtures/dir/a')) + expect(project.getPath()).toEqual fs.resolveOnLoadPath('fixtures/dir') + expect(project.getRootDirectory().path).toEqual fs.resolveOnLoadPath('fixtures/dir') describe "when path is a directory", -> it "sets its path to the directory and updates the root directory", -> - project.setPath(require.resolve('fixtures/dir/a-dir')) - expect(project.getPath()).toEqual require.resolve('fixtures/dir/a-dir') - expect(project.getRootDirectory().path).toEqual require.resolve('fixtures/dir/a-dir') + project.setPath(fs.resolveOnLoadPath('fixtures/dir/a-dir')) + expect(project.getPath()).toEqual fs.resolveOnLoadPath('fixtures/dir/a-dir') + expect(project.getRootDirectory().path).toEqual fs.resolveOnLoadPath('fixtures/dir/a-dir') describe "when path is null", -> it "sets its path and root directory to null", -> @@ -117,7 +118,7 @@ describe "Project", -> expect(project.getRootDirectory()?).toBeFalsy() describe ".getFilePaths()", -> - it "asynchronously returns file paths using a promise", -> + it "returns file paths using a promise", -> paths = null waitsForPromise -> project.getFilePaths().done (foundPaths) -> paths = foundPaths @@ -133,25 +134,25 @@ describe "Project", -> project.getFilePaths().done (foundPaths) -> paths = foundPaths runs -> - expect(paths).not.toContain('a') - expect(paths).toContain('b') + expect(paths).not.toContain(project.resolve('a')) + expect(paths).toContain(project.resolve('b')) describe "when config.core.hideGitIgnoredFiles is true", -> it "ignores files that are present in .gitignore if the project is a git repo", -> config.set "core.hideGitIgnoredFiles", true - project.setPath(require.resolve('fixtures/git/working-dir')) + project.setPath(fs.resolveOnLoadPath('fixtures/git/working-dir')) paths = null waitsForPromise -> project.getFilePaths().done (foundPaths) -> paths = foundPaths - runs -> + runs -> expect(paths).not.toContain('ignored.txt') describe "ignored file name", -> ignoredFile = null beforeEach -> - ignoredFile = fs.join(require.resolve('fixtures/dir'), 'ignored.txt') + ignoredFile = fs.join(fs.resolveOnLoadPath('fixtures/dir'), 'ignored.txt') fs.write(ignoredFile, "") afterEach -> @@ -171,7 +172,7 @@ describe "Project", -> ignoredFile = null beforeEach -> - ignoredFile = fs.join(require.resolve('fixtures/dir'), 'ignored/ignored.txt') + ignoredFile = fs.join(fs.resolveOnLoadPath('fixtures/dir'), 'ignored/ignored.txt') fs.write(ignoredFile, "") afterEach -> @@ -221,7 +222,7 @@ describe "Project", -> range: [[2, 6], [2, 11]] it "works on evil filenames", -> - project.setPath(require.resolve('fixtures/evil-files')) + project.setPath(fs.resolveOnLoadPath('fixtures/evil-files')) paths = [] matches = [] waitsForPromise -> @@ -239,13 +240,13 @@ describe "Project", -> expect(fs.base(paths[4])).toBe "utfa\u0306.md" it "handles breaks in the search subprocess's output following the filename", -> - spyOn $native, 'exec' + spyOn(BufferedProcess.prototype, 'bufferStream') iterator = jasmine.createSpy('iterator') project.scan /a+/, iterator - stdout = $native.exec.argsForCall[0][1].stdout - stdout ":#{require.resolve('fixtures/dir/a')}\n" + stdout = BufferedProcess.prototype.bufferStream.argsForCall[0][1] + stdout ":#{fs.resolveOnLoadPath('fixtures/dir/a')}\n" stdout "1;0 3:aaa bbb\n2;3 2:cc aa cc\n" expect(iterator.argsForCall[0][0]).toEqual @@ -259,9 +260,6 @@ describe "Project", -> range: [[1, 3], [1, 5]] describe "serialization", -> - it "restores the project path and grammar overrides", -> - jsGrammar = _.find syntax.grammars, (grammar) -> grammar.name is 'JavaScript' - project.addGrammarOverrideForPath('/a/b.txt', jsGrammar) + it "restores the project path", -> newProject = Project.deserialize(project.serialize()) expect(newProject.getPath()).toBe project.getPath() - expect(newProject.grammarOverrideForPath('/a/b.txt')).toBe jsGrammar diff --git a/spec/app/root-view-spec.coffee b/spec/app/root-view-spec.coffee index 89c8ef8c1..4935dbd1b 100644 --- a/spec/app/root-view-spec.coffee +++ b/spec/app/root-view-spec.coffee @@ -1,8 +1,8 @@ $ = require 'jquery' -fs = require 'fs' +fs = require 'fs-utils' Project = require 'project' RootView = require 'root-view' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Editor = require 'editor' Pane = require 'pane' {View, $$} = require 'space-pen' @@ -29,7 +29,7 @@ describe "RootView", -> buffer = editor1.getBuffer() editor1.splitRight() viewState = rootView.serialize() - rootView.deactivate() + rootView.remove() window.rootView = deserialize(viewState) rootView.attachToDom() @@ -54,7 +54,7 @@ describe "RootView", -> pane2.focus() viewState = rootView.serialize() - rootView.deactivate() + rootView.remove() window.rootView = deserialize(viewState) rootView.attachToDom() @@ -91,7 +91,7 @@ describe "RootView", -> expect(rootView.getEditors().length).toBe 0 viewState = rootView.serialize() - rootView.deactivate() + rootView.remove() window.rootView = deserialize(viewState) rootView.attachToDom() @@ -223,7 +223,7 @@ describe "RootView", -> it "creates an edit session for the given path as an item on a new pane, and focuses the pane", -> editSession = rootView.open('b') expect(rootView.getActivePane().activeItem).toBe editSession - expect(editSession.getPath()).toBe require.resolve('fixtures/dir/b') + expect(editSession.getPath()).toBe fs.resolveOnLoadPath('fixtures/dir/b') expect(rootView.getActivePane().focus).toHaveBeenCalled() describe "when the changeFocus option is false", -> diff --git a/spec/app/selection-spec.coffee b/spec/app/selection-spec.coffee index 9a56e6118..a10068466 100644 --- a/spec/app/selection-spec.coffee +++ b/spec/app/selection-spec.coffee @@ -1,4 +1,4 @@ -Buffer = require 'buffer' +Buffer = require 'text-buffer' EditSession = require 'edit-session' Range = require 'range' diff --git a/spec/app/syntax-spec.coffee b/spec/app/syntax-spec.coffee index 5cf79f7e3..ad12bee71 100644 --- a/spec/app/syntax-spec.coffee +++ b/spec/app/syntax-spec.coffee @@ -1,51 +1,78 @@ -fs = require 'fs' +fs = require 'fs-utils' describe "the `syntax` global", -> - describe ".grammarForFilePath(filePath)", -> - it "uses the filePath's extension to load the correct grammar", -> - expect(syntax.grammarForFilePath("file.js").name).toBe "JavaScript" + beforeEach -> + atom.activatePackage('text.tmbundle', sync: true) + atom.activatePackage('javascript.tmbundle', sync: true) + atom.activatePackage('coffee-script-tmbundle', sync: true) + atom.activatePackage('ruby.tmbundle', sync: true) - it "uses the filePath's base name if there is no extension", -> - expect(syntax.grammarForFilePath("Rakefile").name).toBe "Ruby" + describe "serialization", -> + it "remembers grammar overrides by path", -> + path = '/foo/bar/file.js' + expect(syntax.selectGrammar(path).name).not.toBe 'Ruby' + syntax.setGrammarOverrideForPath(path, 'source.ruby') + syntax2 = deserialize(syntax.serialize()) + syntax2.addGrammar(grammar) for grammar in syntax.grammars + expect(syntax2.selectGrammar(path).name).toBe 'Ruby' + + describe ".selectGrammar(filePath)", -> + it "can use the filePath to load the correct grammar based on the grammar's filetype", -> + atom.activatePackage('git.tmbundle', sync: true) + + expect(syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js) + expect(syntax.selectGrammar("/tmp/.git/config").name).toBe "Git Config" # based on end of the path (.git/config) + expect(syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile) + expect(syntax.selectGrammar("curb").name).toBe "Plain Text" + expect(syntax.selectGrammar("/hu.git/config").name).toBe "Plain Text" it "uses the filePath's shebang line if the grammar cannot be determined by the extension or basename", -> filePath = require.resolve("fixtures/shebang") - expect(syntax.grammarForFilePath(filePath).name).toBe "Ruby" + expect(syntax.selectGrammar(filePath).name).toBe "Ruby" it "uses the number of newlines in the first line regex to determine the number of lines to test against", -> + atom.activatePackage('property-list.tmbundle', sync: true) + fileContent = "first-line\n" - expect(syntax.grammarForFilePath("dummy.coffee", fileContent).name).toBe "CoffeeScript" + expect(syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript" fileContent = '' - expect(syntax.grammarForFilePath("grammar.tmLanguage", fileContent).name).toBe "Plain Text" + expect(syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Plain Text" fileContent += '\n' - expect(syntax.grammarForFilePath("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)" + expect(syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)" it "doesn't read the file when the file contents are specified", -> filePath = require.resolve("fixtures/shebang") filePathContents = fs.read(filePath) spyOn(fs, 'read').andCallThrough() - expect(syntax.grammarForFilePath(filePath, filePathContents).name).toBe "Ruby" + expect(syntax.selectGrammar(filePath, filePathContents).name).toBe "Ruby" expect(fs.read).not.toHaveBeenCalled() - it "uses the grammar's fileType as a suffix of the full filePath if the grammar cannot be determined by shebang line", -> - expect(syntax.grammarForFilePath("/tmp/.git/config").name).toBe "Git Config" + it "allows the default grammar to be overridden for a path", -> + path = '/foo/bar/file.js' + expect(syntax.selectGrammar(path).name).not.toBe 'Ruby' + syntax.setGrammarOverrideForPath(path, 'source.ruby') + expect(syntax.selectGrammar(path).name).toBe 'Ruby' + syntax.clearGrammarOverrideForPath(path) + expect(syntax.selectGrammar(path).name).not.toBe 'Ruby' - it "uses plain text if no grammar can be found", -> - expect(syntax.grammarForFilePath("this-is-not-a-real-file").name).toBe "Plain Text" + describe ".removeGrammar(grammar)", -> + it "removes the grammar, so it won't be returned by selectGrammar", -> + grammar = syntax.selectGrammar('foo.js') + syntax.removeGrammar(grammar) + expect(syntax.selectGrammar('foo.js').name).not.toBe grammar.name describe ".getProperty(scopeDescriptor)", -> it "returns the property with the most specific scope selector", -> syntax.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42) syntax.addProperties(".source .string.quoted.double", foo: bar: baz: 22) syntax.addProperties(".source", foo: bar: baz: 11) - syntax.addProperties(foo: bar: baz: 1) expect(syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42 expect(syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22 expect(syntax.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11 - expect(syntax.getProperty([".text"], "foo.bar.baz")).toBe 1 + expect(syntax.getProperty([".text"], "foo.bar.baz")).toBeUndefined() it "favors the most recently added properties in the event of a specificity tie", -> syntax.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42) @@ -53,3 +80,12 @@ describe "the `syntax` global", -> expect(syntax.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42 expect(syntax.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22 + + describe ".removeProperties(name)", -> + it "allows properties to be removed by name", -> + syntax.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42) + syntax.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22) + + syntax.removeProperties("b") + expect(syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined() + expect(syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42 diff --git a/spec/app/buffer-spec.coffee b/spec/app/tex-buffer-spec.coffee similarity index 99% rename from spec/app/buffer-spec.coffee rename to spec/app/tex-buffer-spec.coffee index 84b58ddeb..63d50b797 100644 --- a/spec/app/buffer-spec.coffee +++ b/spec/app/tex-buffer-spec.coffee @@ -1,6 +1,6 @@ Project = require 'project' -Buffer = require 'buffer' -fs = require 'fs' +Buffer = require 'text-buffer' +fs = require 'fs-utils' _ = require 'underscore' describe 'Buffer', -> @@ -46,7 +46,7 @@ describe 'Buffer', -> [path, newPath, bufferToChange, eventHandler] = [] beforeEach -> - path = fs.join(require.resolve("fixtures/"), "atom-manipulate-me") + path = fs.join(fs.resolveOnLoadPath("fixtures"), "atom-manipulate-me") newPath = "#{path}-i-moved" fs.write(path, "") bufferToChange = new Buffer(path) diff --git a/spec/app/text-mate-grammar-spec.coffee b/spec/app/text-mate-grammar-spec.coffee index 07d06ca02..276a96496 100644 --- a/spec/app/text-mate-grammar-spec.coffee +++ b/spec/app/text-mate-grammar-spec.coffee @@ -1,14 +1,31 @@ TextMateGrammar = require 'text-mate-grammar' TextMatePackage = require 'text-mate-package' plist = require 'plist' -fs = require 'fs' +fs = require 'fs-utils' _ = require 'underscore' describe "TextMateGrammar", -> grammar = null beforeEach -> - grammar = syntax.grammarForFilePath("hello.coffee") + atom.activatePackage('text.tmbundle', sync: true) + atom.activatePackage('javascript.tmbundle', sync: true) + atom.activatePackage('coffee-script-tmbundle', sync: true) + atom.activatePackage('ruby.tmbundle', sync: true) + grammar = syntax.selectGrammar("hello.coffee") + + describe "@loadSync(path)", -> + it "loads grammars from plists", -> + grammar = TextMateGrammar.loadSync(fs.resolveOnLoadPath('packages/text.tmbundle/Syntaxes/Plain text.plist')) + expect(grammar.scopeName).toBe "text.plain" + {tokens} = grammar.tokenizeLine("this text is so plain. i love it.") + expect(tokens[0]).toEqual value: "this text is so plain. i love it.", scopes: ["text.plain", "meta.paragraph.text"] + + it "loads grammars from cson files", -> + grammar = TextMateGrammar.loadSync(fs.resolveOnLoadPath('package-with-grammars/grammars/alot.cson')) + expect(grammar.scopeName).toBe "source.alot" + {tokens} = grammar.tokenizeLine("this is alot of code") + expect(tokens[1]).toEqual value: "alot", scopes: ["source.alot", "keyword.alot"] describe ".tokenizeLine(line, ruleStack)", -> describe "when the entire line matches a single pattern with no capture groups", -> @@ -31,7 +48,7 @@ describe "TextMateGrammar", -> describe "when the line doesn't match any patterns", -> it "returns the entire line as a single simple token with the grammar's scope", -> - textGrammar = syntax.grammarForFilePath('foo.txt') + textGrammar = syntax.selectGrammar('foo.txt') {tokens} = textGrammar.tokenizeLine("abc def") expect(tokens.length).toBe 1 @@ -108,14 +125,14 @@ describe "TextMateGrammar", -> describe "when the line matches no patterns", -> it "does not infinitely loop", -> - grammar = syntax.grammarForFilePath("sample.txt") + grammar = syntax.selectGrammar("sample.txt") {tokens} = grammar.tokenizeLine('hoo') expect(tokens.length).toBe 1 expect(tokens[0]).toEqual value: 'hoo', scopes: ["text.plain", "meta.paragraph.text"] describe "when the line matches a pattern with a 'contentName'", -> it "creates tokens using the content of contentName as the token name", -> - grammar = syntax.grammarForFilePath("sample.txt") + grammar = syntax.selectGrammar("sample.txt") {tokens} = grammar.tokenizeLine('ok, cool') expect(tokens[0]).toEqual value: 'ok, cool', scopes: ["text.plain", "meta.paragraph.text"] @@ -192,6 +209,9 @@ describe "TextMateGrammar", -> describe "when the pattern includes rules from another grammar", -> it "parses tokens inside the begin/end patterns based on the included grammar's rules", -> + atom.activatePackage('html.tmbundle', sync: true) + atom.activatePackage('ruby-on-rails-tmbundle', sync: true) + grammar = syntax.grammarsByFileType["html.erb"] {tokens} = grammar.tokenizeLine("
<%= User.find(2).full_name %>
") @@ -243,29 +263,38 @@ describe "TextMateGrammar", -> expect(tokens[1].value).toBe " a singleLineComment" it "does not loop infinitely (regression)", -> - grammar = syntax.grammarForFilePath("hello.js") + grammar = syntax.selectGrammar("hello.js") {tokens, ruleStack} = grammar.tokenizeLine("// line comment") {tokens, ruleStack} = grammar.tokenizeLine(" // second line comment with a single leading space", ruleStack) describe "when inside a C block", -> + beforeEach -> + atom.activatePackage('c.tmbundle', sync: true) + it "correctly parses a method. (regression)", -> - grammar = syntax.grammarForFilePath("hello.c") + grammar = syntax.selectGrammar("hello.c") {tokens, ruleStack} = grammar.tokenizeLine("if(1){m()}") expect(tokens[5]).toEqual value: "m", scopes: ["source.c", "meta.block.c", "meta.function-call.c", "support.function.any-method.c"] it "correctly parses nested blocks. (regression)", -> - grammar = syntax.grammarForFilePath("hello.c") + grammar = syntax.selectGrammar("hello.c") {tokens, ruleStack} = grammar.tokenizeLine("if(1){if(1){m()}}") expect(tokens[5]).toEqual value: "if", scopes: ["source.c", "meta.block.c", "keyword.control.c"] expect(tokens[10]).toEqual value: "m", scopes: ["source.c", "meta.block.c", "meta.block.c", "meta.function-call.c", "support.function.any-method.c"] - describe "when the grammar is CSON", -> - it "loads the grammar and correctly parses a keyword", -> - spyOn(syntax, 'addGrammar') - pack = new TextMatePackage(project.resolve("packages/package-with-a-cson-grammar.tmbundle")) - pack.load() - grammar = pack.grammars[0] - expect(grammar).toBeTruthy() - expect(grammar.scopeName).toBe "source.alot" - {tokens} = grammar.tokenizeLine("this is alot of code") - expect(tokens[1]).toEqual value: "alot", scopes: ["source.alot", "keyword.alot"] + describe "when the grammar can infinitely loop over a line", -> + it "aborts tokenization", -> + spyOn(console, 'error') + atom.activatePackage("package-with-infinite-loop-grammar") + grammar = syntax.selectGrammar("something.package-with-infinite-loop-grammar") + {tokens} = grammar.tokenizeLine("abc") + expect(tokens[0].value).toBe "a" + expect(tokens[1].value).toBe "bc" + expect(console.error).toHaveBeenCalled() + + describe "when a grammar has a pattern that has back references in the match value", -> + it "does not special handle the back references and instead allows oniguruma to resolve them", -> + atom.activatePackage('sass.tmbundle', sync: true) + grammar = syntax.selectGrammar("style.scss") + {tokens} = grammar.tokenizeLine("@mixin x() { -moz-selector: whatever; }") + expect(tokens[9]).toEqual value: "-moz-selector", scopes: ["source.css.scss", "meta.property-list.scss", "meta.property-name.scss"] diff --git a/spec/app/text-mate-theme-spec.coffee b/spec/app/text-mate-theme-spec.coffee index b2f6e54fe..16588606c 100644 --- a/spec/app/text-mate-theme-spec.coffee +++ b/spec/app/text-mate-theme-spec.coffee @@ -1,4 +1,4 @@ -fs = require 'fs' +fs = require 'fs-utils' plist = require 'plist' TextMateTheme = require 'text-mate-theme' Theme = require 'theme' @@ -7,7 +7,7 @@ describe "TextMateTheme", -> [theme, themePath] = [] beforeEach -> - themePath = require.resolve(fs.join('fixtures', 'test.tmTheme')) + themePath = fs.resolveOnLoadPath(fs.join('fixtures', 'test.tmTheme')) theme = Theme.load(themePath) afterEach -> diff --git a/spec/app/theme-spec.coffee b/spec/app/theme-spec.coffee index 53349c8ba..86d703b9d 100644 --- a/spec/app/theme-spec.coffee +++ b/spec/app/theme-spec.coffee @@ -1,5 +1,5 @@ $ = require 'jquery' -fs = require 'fs' +fs = require 'fs-utils' Theme = require 'theme' describe "@load(name)", -> @@ -15,7 +15,7 @@ describe "@load(name)", -> it "applies the theme's stylesheet to the current window", -> expect($(".editor").css("background-color")).not.toBe("rgb(20, 20, 20)") - themePath = require.resolve(fs.join('fixtures', 'test.tmTheme')) + themePath = fs.resolveOnLoadPath(fs.join('fixtures', 'test.tmTheme')) theme = Theme.load(themePath) expect($(".editor").css("background-color")).toBe("rgb(20, 20, 20)") diff --git a/spec/app/tokenized-buffer-spec.coffee b/spec/app/tokenized-buffer-spec.coffee index 86bd50520..4f7ad41ce 100644 --- a/spec/app/tokenized-buffer-spec.coffee +++ b/spec/app/tokenized-buffer-spec.coffee @@ -1,6 +1,6 @@ TokenizedBuffer = require 'tokenized-buffer' LanguageMode = require 'language-mode' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Range = require 'range' _ = require 'underscore' @@ -8,6 +8,7 @@ describe "TokenizedBuffer", -> [editSession, tokenizedBuffer, buffer, changeHandler] = [] beforeEach -> + atom.activatePackage('javascript.tmbundle', sync: true) # enable async tokenization TokenizedBuffer.prototype.chunkSize = 5 jasmine.unspy(TokenizedBuffer.prototype, 'tokenizeInBackground') @@ -298,6 +299,7 @@ describe "TokenizedBuffer", -> describe "when the buffer contains hard-tabs", -> beforeEach -> + atom.activatePackage('coffee-script-tmbundle', sync: true) tabLength = 2 editSession = project.buildEditSession('sample-with-tabs.coffee', { tabLength }) buffer = editSession.buffer @@ -328,6 +330,7 @@ describe "TokenizedBuffer", -> describe "when a Git commit message file is tokenized", -> beforeEach -> + atom.activatePackage('git.tmbundle', sync: true) editSession = project.buildEditSession('COMMIT_EDITMSG', autoIndent: false) buffer = editSession.buffer tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer @@ -355,6 +358,7 @@ describe "TokenizedBuffer", -> describe "when a C++ source file is tokenized", -> beforeEach -> + atom.activatePackage('c.tmbundle', sync: true) editSession = project.buildEditSession('includes.cc', autoIndent: false) buffer = editSession.buffer tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer @@ -403,6 +407,8 @@ describe "TokenizedBuffer", -> describe "when an Objective-C source file is tokenized", -> beforeEach -> + atom.activatePackage('c.tmbundle', sync: true) + atom.activatePackage('objective-c.tmbundle', sync: true) editSession = project.buildEditSession('function.mm', autoIndent: false) buffer = editSession.buffer tokenizedBuffer = editSession.displayBuffer.tokenizedBuffer diff --git a/spec/app/undo-manager-spec.coffee b/spec/app/undo-manager-spec.coffee index 6134a4da2..e213751d4 100644 --- a/spec/app/undo-manager-spec.coffee +++ b/spec/app/undo-manager-spec.coffee @@ -1,5 +1,5 @@ UndoManager = require 'undo-manager' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Range = require 'range' describe "UndoManager", -> diff --git a/spec/app/window-spec.coffee b/spec/app/window-spec.coffee index 4abcf6d5b..0615cdc91 100644 --- a/spec/app/window-spec.coffee +++ b/spec/app/window-spec.coffee @@ -1,5 +1,5 @@ $ = require 'jquery' -fs = require 'fs' +fs = require 'fs-utils' {less} = require 'less' describe "Window", -> @@ -8,12 +8,11 @@ describe "Window", -> beforeEach -> spyOn(atom, 'getPathToOpen').andReturn(project.getPath()) window.handleWindowEvents() - window.buildProjectAndRootView() + window.deserializeWindowState() projectPath = project.getPath() afterEach -> window.shutdown() - atom.setRootViewStateForPath(projectPath, null) $(window).off 'beforeunload' describe "when the window is loaded", -> @@ -95,7 +94,7 @@ describe "Window", -> $('head style[id*="css.css"]').remove() - it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", -> + it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", -> lessPath = project.resolve('sample.less') lengthBefore = $('head style').length requireStylesheet(lessPath) @@ -118,7 +117,16 @@ describe "Window", -> expect($('head style').length).toBe lengthBefore + 1 $('head style[id*="sample.less"]').remove() - describe ".disableStyleSheet(path)", -> + it "supports requiring css and less stylesheets without an explicit extension", -> + requireStylesheet 'fixtures/css' + expect($('head style[id*="css.css"]').attr('id')).toBe project.resolve('css.css') + requireStylesheet 'fixtures/sample' + expect($('head style[id*="sample.less"]').attr('id')).toBe project.resolve('sample.less') + + $('head style[id*="css.css"]').remove() + $('head style[id*="sample.less"]').remove() + + describe ".removeStylesheet(path)", -> it "removes styling applied by given stylesheet path", -> cssPath = require.resolve(fs.join("fixtures", "css.css")) @@ -129,18 +137,23 @@ describe "Window", -> expect($(document.body).css('font-weight')).not.toBe("bold") describe ".shutdown()", -> - it "saves the serialized state of the project and root view to the atom object so it can be rehydrated after reload", -> + it "saves the serialized state of the window so it can be deserialized after reload", -> projectPath = project.getPath() - expect(atom.getRootViewStateForPath(projectPath)).toBeUndefined() + expect(atom.getWindowState()).toEqual {} + # JSON.stringify removes keys with undefined values rootViewState = JSON.parse(JSON.stringify(rootView.serialize())) projectState = JSON.parse(JSON.stringify(project.serialize())) + syntaxState = JSON.parse(JSON.stringify(syntax.serialize())) window.shutdown() - expect(atom.getRootViewStateForPath(projectPath)).toEqual - project: projectState - rootView: rootViewState + windowState = atom.getWindowState() + expect(windowState.rootView).toEqual rootViewState + expect(windowState.project).toEqual projectState + expect(windowState.syntax).toEqual syntaxState + + expect(atom.saveWindowState).toHaveBeenCalled() it "unsubscribes from all buffers", -> rootView.open('sample.js') @@ -153,10 +166,10 @@ describe "Window", -> expect(buffer.subscriptionCount()).toBe 0 it "only serializes window state the first time it is called", -> - deactivateSpy = spyOn(atom, "setRootViewStateForPath").andCallThrough() + window.shutdown() window.shutdown() - expect(atom.setRootViewStateForPath.callCount).toBe 1 + expect(atom.saveWindowState.callCount).toBe 1 describe ".installAtomCommand(commandPath)", -> commandPath = '/tmp/installed-atom-command/atom' diff --git a/spec/fixtures/git/working-dir/ignored.txt b/spec/fixtures/git/working-dir/ignored.txt deleted file mode 100644 index 8ee8bb6eb..000000000 --- a/spec/fixtures/git/working-dir/ignored.txt +++ /dev/null @@ -1 +0,0 @@ -i am ignored diff --git a/spec/fixtures/packages/package-with-a-cson-grammar.tmbundle/Snippets/test.cson b/spec/fixtures/packages/package-with-a-cson-grammar.tmbundle/Snippets/test.cson deleted file mode 100644 index a82d8447a..000000000 --- a/spec/fixtures/packages/package-with-a-cson-grammar.tmbundle/Snippets/test.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'Really' -'scope': 'source.alot' -'tabTrigger': 'really' -'content': 'I really like $1 alot$0' diff --git a/spec/fixtures/packages/package-with-activation-events/main.coffee b/spec/fixtures/packages/package-with-activation-events/index.coffee similarity index 86% rename from spec/fixtures/packages/package-with-activation-events/main.coffee rename to spec/fixtures/packages/package-with-activation-events/index.coffee index d57ca7c24..91f2230b1 100644 --- a/spec/fixtures/packages/package-with-activation-events/main.coffee +++ b/spec/fixtures/packages/package-with-activation-events/index.coffee @@ -10,7 +10,5 @@ module.exports = activate: -> @activateCallCount++ rootView.getActiveView()?.command 'activation-event', => + console.log "ACTIVATION EVENT" @activationEventCallCount++ - - serialize: -> - previousData: 'overwritten' diff --git a/spec/fixtures/packages/package-with-activation-events/package.cson b/spec/fixtures/packages/package-with-activation-events/package.cson index 42d3eb78d..45d8dfea1 100644 --- a/spec/fixtures/packages/package-with-activation-events/package.cson +++ b/spec/fixtures/packages/package-with-activation-events/package.cson @@ -1,3 +1,2 @@ 'activationEvents': ['activation-event'] 'deferredDeserializers': ['Foo'] -'main': 'main' diff --git a/spec/fixtures/packages/textmate-package.tmbundle/Snippets/.hidden-file b/spec/fixtures/packages/package-with-broken-snippets.tmbundle/Snippets/.hidden-file similarity index 100% rename from spec/fixtures/packages/textmate-package.tmbundle/Snippets/.hidden-file rename to spec/fixtures/packages/package-with-broken-snippets.tmbundle/Snippets/.hidden-file diff --git a/spec/fixtures/packages/textmate-package.tmbundle/Snippets/invalid.plist b/spec/fixtures/packages/package-with-broken-snippets.tmbundle/Snippets/invalid.plist similarity index 100% rename from spec/fixtures/packages/textmate-package.tmbundle/Snippets/invalid.plist rename to spec/fixtures/packages/package-with-broken-snippets.tmbundle/Snippets/invalid.plist diff --git a/spec/fixtures/packages/package-with-config-defaults/index.coffee b/spec/fixtures/packages/package-with-config-defaults/index.coffee new file mode 100644 index 000000000..5e0b1eed6 --- /dev/null +++ b/spec/fixtures/packages/package-with-config-defaults/index.coffee @@ -0,0 +1,3 @@ +module.exports = + configDefaults: + numbers: { one: 1, two: 2 } diff --git a/spec/fixtures/packages/package-with-deactivate/index.coffee b/spec/fixtures/packages/package-with-deactivate/index.coffee new file mode 100644 index 000000000..65517bacd --- /dev/null +++ b/spec/fixtures/packages/package-with-deactivate/index.coffee @@ -0,0 +1,3 @@ +module.exports = + activate: -> + deactivate: -> diff --git a/spec/fixtures/packages/package-with-grammars/grammars/alittle.cson b/spec/fixtures/packages/package-with-grammars/grammars/alittle.cson new file mode 100644 index 000000000..c72bea137 --- /dev/null +++ b/spec/fixtures/packages/package-with-grammars/grammars/alittle.cson @@ -0,0 +1,12 @@ +'fileTypes': ['alittle'] +'name': 'Alittle' +'scopeName': 'source.alittle' + +'patterns': [ + { + 'captures': + '0': + 'name': 'keyword.alittle' + 'match': 'alittle' + } +] diff --git a/spec/fixtures/packages/package-with-a-cson-grammar.tmbundle/Syntaxes/alot.cson b/spec/fixtures/packages/package-with-grammars/grammars/alot.cson similarity index 79% rename from spec/fixtures/packages/package-with-a-cson-grammar.tmbundle/Syntaxes/alot.cson rename to spec/fixtures/packages/package-with-grammars/grammars/alot.cson index d30d33f56..c8999a942 100644 --- a/spec/fixtures/packages/package-with-a-cson-grammar.tmbundle/Syntaxes/alot.cson +++ b/spec/fixtures/packages/package-with-grammars/grammars/alot.cson @@ -1,6 +1,7 @@ -'fileTypes': ['alot'] +'fileTypes': ['alot', 'foobizbang'] 'name': 'Alot' 'scopeName': 'source.alot' + 'patterns': [ { 'captures': diff --git a/spec/fixtures/packages/package-with-index/index.coffee b/spec/fixtures/packages/package-with-index/index.coffee new file mode 100644 index 000000000..825eb4055 --- /dev/null +++ b/spec/fixtures/packages/package-with-index/index.coffee @@ -0,0 +1,2 @@ +module.exports = +activate: -> diff --git a/spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson b/spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson new file mode 100644 index 000000000..8ac183c23 --- /dev/null +++ b/spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson @@ -0,0 +1,18 @@ +'fileTypes': ['package-with-infinite-loop-grammar'] +'name': 'package-with-infinite-loop-grammar' +'scopeName': 'source.package-with-infinite-loop-grammar' + +# This grammar should loop forever if the line contains an `a` +'patterns': [ + { + 'name': 'start' + 'begin': '^' + 'end': '$' + 'patterns': [ + { + name: 'negative-look-ahead' + match: "(?!a)" + } + ] + } +] diff --git a/spec/fixtures/packages/package-with-module/keymaps/keymap-1.cson b/spec/fixtures/packages/package-with-keymaps/keymaps/keymap-1.cson similarity index 100% rename from spec/fixtures/packages/package-with-module/keymaps/keymap-1.cson rename to spec/fixtures/packages/package-with-keymaps/keymaps/keymap-1.cson diff --git a/spec/fixtures/packages/package-with-module/keymaps/keymap-2.cson b/spec/fixtures/packages/package-with-keymaps/keymaps/keymap-2.cson similarity index 100% rename from spec/fixtures/packages/package-with-module/keymaps/keymap-2.cson rename to spec/fixtures/packages/package-with-keymaps/keymaps/keymap-2.cson diff --git a/spec/fixtures/packages/package-with-module/keymaps/keymap-3.cjson b/spec/fixtures/packages/package-with-keymaps/keymaps/keymap-3.cjson similarity index 100% rename from spec/fixtures/packages/package-with-module/keymaps/keymap-3.cjson rename to spec/fixtures/packages/package-with-keymaps/keymaps/keymap-3.cjson diff --git a/spec/fixtures/packages/package-with-main/main-module.coffee b/spec/fixtures/packages/package-with-main/main-module.coffee new file mode 100644 index 000000000..46920ab78 --- /dev/null +++ b/spec/fixtures/packages/package-with-main/main-module.coffee @@ -0,0 +1,2 @@ +module.exports = +activate: -> \ No newline at end of file diff --git a/spec/fixtures/packages/package-with-main/package.cson b/spec/fixtures/packages/package-with-main/package.cson new file mode 100644 index 000000000..a93a109c4 --- /dev/null +++ b/spec/fixtures/packages/package-with-main/package.cson @@ -0,0 +1 @@ +'main': 'main-module.coffee' \ No newline at end of file diff --git a/spec/fixtures/packages/package-with-module/index.coffee b/spec/fixtures/packages/package-with-module/index.coffee deleted file mode 100644 index 84d5c12a1..000000000 --- a/spec/fixtures/packages/package-with-module/index.coffee +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = - configDefaults: - numbers: { one: 1, two: 2 } - - someNumber: 0 - - activate: -> - @someNumber = 1 - - deactivate: -> - - serialize: -> - {@someNumber} diff --git a/spec/fixtures/packages/package-with-module/stylesheets/styles.css b/spec/fixtures/packages/package-with-module/stylesheets/styles.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/spec/fixtures/packages/package-with-scoped-properties/scoped-properties/omg.cson b/spec/fixtures/packages/package-with-scoped-properties/scoped-properties/omg.cson new file mode 100644 index 000000000..4a3037963 --- /dev/null +++ b/spec/fixtures/packages/package-with-scoped-properties/scoped-properties/omg.cson @@ -0,0 +1,3 @@ +'.source.omg': + 'editor': + 'increaseIndentPattern': '^a' diff --git a/spec/fixtures/packages/package-with-serialization/index.coffee b/spec/fixtures/packages/package-with-serialization/index.coffee new file mode 100644 index 000000000..54949113c --- /dev/null +++ b/spec/fixtures/packages/package-with-serialization/index.coffee @@ -0,0 +1,6 @@ +module.exports = + activate: ({@someNumber}) -> + @someNumber ?= 1 + + serialize: -> + {@someNumber} diff --git a/spec/fixtures/packages/package-with-stylesheets-manifest/package.cson b/spec/fixtures/packages/package-with-stylesheets-manifest/package.cson new file mode 100644 index 000000000..45ccf32bc --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets-manifest/package.cson @@ -0,0 +1 @@ +stylesheets: ['2', '1'] diff --git a/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css b/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css new file mode 100644 index 000000000..c16849c0e --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css @@ -0,0 +1,3 @@ +#jasmine-content { + font-size: 1px; +} diff --git a/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less b/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less new file mode 100644 index 000000000..c0ffbc897 --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less @@ -0,0 +1,5 @@ +@size: 2px; + +#jasmine-content { + font-size: @size; +} diff --git a/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css b/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css new file mode 100644 index 000000000..f43408c63 --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css @@ -0,0 +1,3 @@ +#jasmine-content { + font-size: 3px; +} diff --git a/spec/fixtures/packages/package-with-stylesheets/stylesheets/1.css b/spec/fixtures/packages/package-with-stylesheets/stylesheets/1.css new file mode 100644 index 000000000..c16849c0e --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets/stylesheets/1.css @@ -0,0 +1,3 @@ +#jasmine-content { + font-size: 1px; +} diff --git a/spec/fixtures/packages/package-with-stylesheets/stylesheets/2.less b/spec/fixtures/packages/package-with-stylesheets/stylesheets/2.less new file mode 100644 index 000000000..c0ffbc897 --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets/stylesheets/2.less @@ -0,0 +1,5 @@ +@size: 2px; + +#jasmine-content { + font-size: @size; +} diff --git a/spec/fixtures/packages/package-with-stylesheets/stylesheets/3.css b/spec/fixtures/packages/package-with-stylesheets/stylesheets/3.css new file mode 100644 index 000000000..f43408c63 --- /dev/null +++ b/spec/fixtures/packages/package-with-stylesheets/stylesheets/3.css @@ -0,0 +1,3 @@ +#jasmine-content { + font-size: 3px; +} diff --git a/spec/fixtures/packages/package-without-module/package.cson b/spec/fixtures/packages/package-without-module/package.cson new file mode 100644 index 000000000..c6e451934 --- /dev/null +++ b/spec/fixtures/packages/package-without-module/package.cson @@ -0,0 +1 @@ +"name": "perfect" diff --git a/spec/fixtures/symlink-to-file b/spec/fixtures/symlink-to-file new file mode 120000 index 000000000..cdd38b0e4 --- /dev/null +++ b/spec/fixtures/symlink-to-file @@ -0,0 +1 @@ +sample.js \ No newline at end of file diff --git a/spec/fixtures/test.tmbundle/Preferences/Disable Indention Correction.tmPreferences b/spec/fixtures/test.tmbundle/Preferences/Disable Indention Correction.tmPreferences deleted file mode 100644 index 63c91ab3f..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Disable Indention Correction.tmPreferences +++ /dev/null @@ -1,19 +0,0 @@ - - - - - name - Disable Indention Correction - scope - text - text source - settings - - disableIndentCorrections - 1 - indentOnPaste - simple - - uuid - 29B976F9-853F-43FF-AA50-7A6A518EDC81 - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Markup style: Bold.plist b/spec/fixtures/test.tmbundle/Preferences/Markup style: Bold.plist deleted file mode 100644 index 5a63bd8b7..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Markup style: Bold.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - name - Style: Bold - scope - markup.bold - settings - - bold - 1 - - uuid - A088E2CA-03E7-4A8C-855C-AC954E739D6D - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Markup style: Italic.plist b/spec/fixtures/test.tmbundle/Preferences/Markup style: Italic.plist deleted file mode 100644 index 9ea3216d3..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Markup style: Italic.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - name - Style: Italic - scope - markup.italic - settings - - italic - 1 - - uuid - 2EE6D01F-50BC-434B-BE45-54D29CACB3E0 - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Markup style: Underline.plist b/spec/fixtures/test.tmbundle/Preferences/Markup style: Underline.plist deleted file mode 100644 index 11a01ca40..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Markup style: Underline.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - name - Style: Underline - scope - markup.underline - settings - - underline - 1 - - uuid - 4CCD8369-40E4-422A-ABE7-C32F3721AFEF - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Miscellaneous.plist b/spec/fixtures/test.tmbundle/Preferences/Miscellaneous.plist deleted file mode 100644 index 04ffaf9d8..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Miscellaneous.plist +++ /dev/null @@ -1,65 +0,0 @@ - - - - - name - Miscellaneous - settings - - highlightPairs - - - ( - ) - - - { - } - - - [ - ] - - - - - - - - - - - smartTypingPairs - - - " - " - - - ( - ) - - - { - } - - - [ - ] - - - - - - - - - - - unIndentedLinePattern - ^\s*$ - - uuid - 3E8C2307-8175-4A58-BE07-785713D5837A - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Spell checking.plist b/spec/fixtures/test.tmbundle/Preferences/Spell checking.plist deleted file mode 100644 index 3ef7e991a..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Spell checking.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - name - Spell Checking: Disable - scope - markup.underline.link, markup.raw - settings - - spellChecking - 0 - - uuid - 613405D5-67B6-4281-94C9-9148E54C66FB - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Style: Numbered List.tmPreferences b/spec/fixtures/test.tmbundle/Preferences/Style: Numbered List.tmPreferences deleted file mode 100644 index d42f54a77..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Style: Numbered List.tmPreferences +++ /dev/null @@ -1,22 +0,0 @@ - - - - - name - Style: Numbered List - scope - markup.list.numbered - settings - - indentedSoftWrap - - format - ${0/\S/ /g} - match - \A\s*((\d+\.|[-*]|#+)\s+|(?=\w)) - - - uuid - EEDAA012-BFBD-4FE8-9253-4EDC5F7309F1 - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Style: Raw.tmPreferences b/spec/fixtures/test.tmbundle/Preferences/Style: Raw.tmPreferences deleted file mode 100644 index 0cfde4b08..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Style: Raw.tmPreferences +++ /dev/null @@ -1,17 +0,0 @@ - - - - - name - Style: Raw - scope - markup.raw.block - settings - - softWrap - - - uuid - 47A88FB7-A084-48F6-9B54-078E9C888BE6 - - diff --git a/spec/fixtures/test.tmbundle/Preferences/Style: Unnumbered List.tmPreferences b/spec/fixtures/test.tmbundle/Preferences/Style: Unnumbered List.tmPreferences deleted file mode 100644 index 1c92881fd..000000000 --- a/spec/fixtures/test.tmbundle/Preferences/Style: Unnumbered List.tmPreferences +++ /dev/null @@ -1,22 +0,0 @@ - - - - - name - Style: Unnumbered List - scope - markup.list.unnumbered - settings - - indentedSoftWrap - - format - ${0/\S/ /g} - match - \A\s*[-*]\s+ - - - uuid - 93CBCCEB-32BE-41F3-9F00-B975831F33EC - - diff --git a/spec/fixtures/test.tmbundle/Preferences/empty.plist b/spec/fixtures/test.tmbundle/Preferences/empty.plist deleted file mode 100644 index e69de29bb..000000000 diff --git a/spec/fixtures/test.tmbundle/Snippets/010 Copyright.plist b/spec/fixtures/test.tmbundle/Snippets/010 Copyright.plist deleted file mode 100644 index 3d43183c1..000000000 --- a/spec/fixtures/test.tmbundle/Snippets/010 Copyright.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - content - (c) Copyright `date +%Y` $TM_FULLNAME. All Rights Reserved. - name - Copyright Notice - tabTrigger - c) - uuid - BC8B89E4-5F16-11D9-B9C3-000D93589AF6 - - diff --git a/spec/fixtures/test.tmbundle/Snippets/Conitnue bullet.plist b/spec/fixtures/test.tmbundle/Snippets/Conitnue bullet.plist deleted file mode 100644 index 4704f7906..000000000 --- a/spec/fixtures/test.tmbundle/Snippets/Conitnue bullet.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - content - -• - keyEquivalent -  - name - Continue Bullet - scope - meta.bullet-point - uuid - C30BA263-B10E-11D9-9975-000D93589AF6 - - diff --git a/spec/fixtures/test.tmbundle/Snippets/Conitnue light bullet.plist b/spec/fixtures/test.tmbundle/Snippets/Conitnue light bullet.plist deleted file mode 100644 index 2c0cd2a80..000000000 --- a/spec/fixtures/test.tmbundle/Snippets/Conitnue light bullet.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - content - - keyEquivalent -  - name - Continue Light Bullet - scope - meta.bullet-point.light - uuid - EA149DAB-B10E-11D9-9975-000D93589AF6 - - diff --git a/spec/fixtures/test.tmbundle/Snippets/Conitnue star bullet.plist b/spec/fixtures/test.tmbundle/Snippets/Conitnue star bullet.plist deleted file mode 100644 index 81dc40471..000000000 --- a/spec/fixtures/test.tmbundle/Snippets/Conitnue star bullet.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - content - -* - keyEquivalent -  - name - Continue Star Bullet - scope - meta.bullet-point.star - uuid - B5E22191-B151-11D9-85C9-000D93589AF6 - - diff --git a/spec/fixtures/test.tmbundle/Snippets/Insert ISO date.plist b/spec/fixtures/test.tmbundle/Snippets/Insert ISO date.plist deleted file mode 100644 index c2b2f79b8..000000000 --- a/spec/fixtures/test.tmbundle/Snippets/Insert ISO date.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - content - `date +%Y-%m-%d` - name - Current Date — YYYY-MM-DD - tabTrigger - isoD - uuid - C9CAF012-6E50-11D9-AA12-000D93589AF6 - - diff --git a/spec/fixtures/test.tmbundle/Snippets/Lorem ipsum.plist b/spec/fixtures/test.tmbundle/Snippets/Lorem ipsum.plist deleted file mode 100644 index a30cff0d4..000000000 --- a/spec/fixtures/test.tmbundle/Snippets/Lorem ipsum.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - content - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - name - Lorem ipsum - tabTrigger - lorem - uuid - BA9A2B17-DA89-49A5-809B-AC7510C24625 - - diff --git a/spec/fixtures/test.tmbundle/Syntaxes/Empty.plist b/spec/fixtures/test.tmbundle/Syntaxes/Empty.plist deleted file mode 100644 index e69de29bb..000000000 diff --git a/spec/fixtures/test.tmbundle/Syntaxes/Test.plist b/spec/fixtures/test.tmbundle/Syntaxes/Test.plist deleted file mode 100644 index 315d4ce16..000000000 --- a/spec/fixtures/test.tmbundle/Syntaxes/Test.plist +++ /dev/null @@ -1,35 +0,0 @@ - - - - - fileTypes - - .testo - - keyEquivalent - ^~P - name - Test - patterns - - - captures - - 1 - - name - punctuation.definition.item.text - - - match - ^\s*//.*$\n? - name - comment - - - scopeName - text.test - uuid - 313DD4FA-B10E-11D9-9F75-000D93589AF6 - - diff --git a/spec/jasmine-focused.coffee b/spec/jasmine-focused.coffee new file mode 100644 index 000000000..25777a8cf --- /dev/null +++ b/spec/jasmine-focused.coffee @@ -0,0 +1,30 @@ +setGlobalFocusPriority = (priority) -> + env = jasmine.getEnv() + env.focusPriority = 1 unless env.focusPriority + env.focusPriority = priority if priority > env.focusPriority + +window.fdescribe = (description, specDefinitions, priority) -> + priority = 1 unless priority + setGlobalFocusPriority(priority) + suite = describe(description, specDefinitions) + suite.focusPriority = priority + suite + +window.ffdescribe = (description, specDefinitions) -> + fdescribe(description, specDefinitions, 2) + +window.fffdescribe = (description, specDefinitions) -> + fdescribe(description, specDefinitions, 3) + +window.fit = (description, definition, priority) -> + priority = 1 unless priority + setGlobalFocusPriority(priority) + spec = it(description, definition) + spec.focusPriority = priority + spec + +window.ffit = (description, specDefinitions) -> + fit(description, specDefinitions, 2) + +window.fffit = (description, specDefinitions) -> + fit(description, specDefinitions, 3) diff --git a/vendor/jasmine-helper.coffee b/spec/jasmine-helper.coffee similarity index 69% rename from vendor/jasmine-helper.coffee rename to spec/jasmine-helper.coffee index 40525da33..fb6175ae0 100644 --- a/vendor/jasmine-helper.coffee +++ b/spec/jasmine-helper.coffee @@ -1,8 +1,17 @@ +window.nakedLoad = (file) -> + fs = require 'fs-utils' + file = require.resolve(file) + code = fs.read(file) + if fs.extension(file) is '.coffee' + require('coffee-script').eval(code, filename: file) + else + window.eval("#{code}\n//@ sourceURL=#{file}") + module.exports.runSpecSuite = (specSuite, logErrors=true) -> {$$} = require 'space-pen' nakedLoad 'jasmine' nakedLoad 'jasmine-console-reporter' - nakedLoad 'jasmine-focused' + require 'jasmine-focused' AtomReporter = require 'atom-reporter' @@ -14,7 +23,6 @@ module.exports.runSpecSuite = (specSuite, logErrors=true) -> else new AtomReporter() - require specSuite jasmineEnv = jasmine.getEnv() jasmineEnv.addReporter(reporter) diff --git a/spec/spec-bootstrap.coffee b/spec/spec-bootstrap.coffee index dbffbeece..f3a961207 100644 --- a/spec/spec-bootstrap.coffee +++ b/spec/spec-bootstrap.coffee @@ -1,6 +1,10 @@ -require 'atom' -atom.show() -{runSpecSuite} = require 'jasmine-helper' +try + require 'atom' + atom.show() + {runSpecSuite} = require 'jasmine-helper' -document.title = "Spec Suite" -runSpecSuite "spec-suite" + document.title = "Spec Suite" + runSpecSuite "spec-suite" +catch e + console.error(e.stack) + atom.exit(1) if window.location.params.exitWhenDone diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 8518fa6c3..65a1b85dd 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -12,12 +12,12 @@ Directory = require 'directory' File = require 'file' Editor = require 'editor' TokenizedBuffer = require 'tokenized-buffer' -fs = require 'fs' +fs = require 'fs-utils' RootView = require 'root-view' Git = require 'git' -requireStylesheet "jasmine.less" -fixturePackagesPath = require.resolve('fixtures/packages') -require.paths.unshift(fixturePackagesPath) +requireStylesheet "jasmine" +fixturePackagesPath = fs.resolveOnLoadPath('fixtures/packages') +config.packageDirPaths.unshift(fixturePackagesPath) keymap.loadBundledKeymaps() [bindingSetsToRestore, bindingSetsByFirstKeystrokeToRestore] = [] @@ -30,15 +30,19 @@ jasmine.getEnv().defaultTimeoutInterval = 5000 beforeEach -> jQuery.fx.off = true - window.project = new Project(require.resolve('fixtures')) + window.project = new Project(fs.resolveOnLoadPath('fixtures')) window.git = Git.open(project.getPath()) window.project.on 'path-changed', -> window.git?.destroy() window.git = Git.open(window.project.getPath()) window.resetTimeouts() - atom.atomPackageStates = {} - atom.loadedPackages = [] + atom.packageStates = {} + spyOn(atom, 'saveWindowState') + spyOn(atom, 'getSavedWindowState').andReturn(null) + $native.setWindowState('') + syntax.clearGrammarOverrides() + syntax.clearProperties() # used to reset keymap after each spec bindingSetsToRestore = _.clone(keymap.bindingSets) @@ -73,8 +77,9 @@ beforeEach -> afterEach -> keymap.bindingSets = bindingSetsToRestore keymap.bindingSetsByFirstKeystrokeToRestore = bindingSetsByFirstKeystrokeToRestore + atom.deactivatePackages() if rootView? - rootView.deactivate?() + rootView.remove?() window.rootView = null if project? project.destroy() @@ -86,28 +91,9 @@ afterEach -> ensureNoPathSubscriptions() atom.pendingModals = [[]] atom.presentingModal = false + syntax.off() waits(0) # yield to ui thread to make screen update more frequently -window.loadPackage = (name, options={}) -> - Package = require 'package' - packagePath = _.find atom.getPackagePaths(), (packagePath) -> fs.base(packagePath) == name - if pack = Package.build(packagePath) - pack.load(options) - atom.loadedPackages.push(pack) - pack.deferActivation = false if options.activateImmediately - pack.activate() - pack - -# Specs rely on TextMate bundles (but not atom packages) -window.loadTextMatePackages = -> - TextMatePackage = require 'text-mate-package' - config.packageDirPaths.unshift(fixturePackagesPath) - window.textMatePackages = [] - for path in atom.getPackagePaths() when TextMatePackage.testName(path) - window.textMatePackages.push window.loadPackage(fs.base(path)) - -window.loadTextMatePackages() - ensureNoPathSubscriptions = -> watchedPaths = $native.getWatchedPaths() $native.unwatchAllPaths() diff --git a/spec/spec-suite.coffee b/spec/spec-suite.coffee index 67da12ee2..0c7ebc37e 100644 --- a/spec/spec-suite.coffee +++ b/spec/spec-suite.coffee @@ -1,13 +1,15 @@ -fs = require 'fs' -require 'spec-helper' +require 'window' +measure 'spec suite require time', -> + fs = require 'fs-utils' + require 'spec-helper' -# Run core specs -for path in fs.listTree(require.resolve("spec")) when /-spec\.coffee$/.test path - require path + # Run core specs + for path in fs.listTree(fs.resolveOnLoadPath("spec")) when /-spec\.coffee$/.test path + require path -# Run extension specs -for packageDirPath in config.packageDirPaths - for packagePath in fs.list(packageDirPath) - for path in fs.listTree(fs.join(packagePath, "spec")) when /-spec\.coffee$/.test path - require path + # Run extension specs + for packageDirPath in config.packageDirPaths + for packagePath in fs.list(packageDirPath) + for path in fs.listTree(fs.join(packagePath, "spec")) when /-spec\.coffee$/.test path + require path diff --git a/spec/stdlib/child-process-spec.coffee b/spec/stdlib/child-process-spec.coffee deleted file mode 100644 index e594d2b7f..000000000 --- a/spec/stdlib/child-process-spec.coffee +++ /dev/null @@ -1,144 +0,0 @@ -ChildProcess = require 'child-process' - -describe 'Child Processes', -> - describe ".exec(command, options)", -> - [stderrHandler, stdoutHandler] = [] - - beforeEach -> - stderrHandler = jasmine.createSpy "stderrHandler" - stdoutHandler = jasmine.createSpy "stdoutHandler" - - it "returns a promise that resolves to stdout and stderr", -> - waitsForPromise -> - cmd = "echo 'good' && echo 'bad' >&2" - standardOutput = '' - errorOutput = '' - options = - stdout: (data) -> - standardOutput += data - stderr: (data) -> - errorOutput += data - - ChildProcess.exec(cmd, options).done -> - expect(standardOutput).toBe 'good\n' - expect(errorOutput).toBe 'bad\n' - - describe "when options are given", -> - it "calls the options.stdout callback when new data is received on stdout", -> - cmd = "echo 'first' && sleep .1 && echo 'second' && sleep .1 && echo 'third'" - ChildProcess.exec(cmd, stdout: stdoutHandler) - - waitsFor -> - stdoutHandler.callCount > 2 - - runs -> - expect(stdoutHandler.argsForCall[0][0]).toBe "first\n" - expect(stdoutHandler.argsForCall[1][0]).toBe "second\n" - expect(stdoutHandler.argsForCall[2][0]).toBe "third\n" - - it "calls the options.stderr callback when new data is received on stderr", -> - cmd = "echo '1111' >&2 && sleep .1 && echo '2222' >&2" - ChildProcess.exec(cmd, stderr: stderrHandler) - - waitsFor -> - stderrHandler.callCount > 1 - - runs -> - expect(stderrHandler.argsForCall[0][0]).toBe "1111\n" - expect(stderrHandler.argsForCall[1][0]).toBe "2222\n" - - describe "when the `bufferLines` option is true ", -> - [simulateStdout, simulateStderr] = [] - - beforeEach -> - spyOn($native, 'exec') - ChildProcess.exec("print_the_things", bufferLines: true, stdout: stdoutHandler, stderr: stderrHandler) - { stdout, stderr } = $native.exec.argsForCall[0][1] - simulateStdout = stdout - simulateStderr = stderr - - it "only triggers stdout callbacks with complete lines", -> - simulateStdout """ - I am a full line - I am part of """ - - expect(stdoutHandler).toHaveBeenCalledWith("I am a full line\n") - stdoutHandler.reset() - - simulateStdout """ - a line - I am another full line\n - """ - - expect(stdoutHandler).toHaveBeenCalledWith """ - I am part of a line - I am another full line\n - """ - - it "only triggers stderr callbacks with complete lines", -> - simulateStderr """ - I am a full line - I am part of """ - - expect(stderrHandler).toHaveBeenCalledWith("I am a full line\n") - stdoutHandler.reset() - - simulateStderr """ - a line - I am another full line\n - """ - - expect(stderrHandler).toHaveBeenCalledWith """ - I am part of a line - I am another full line\n - """ - - describe "when the command fails", -> - it "executes the callback with error set to the exit status", -> - waitsForPromise shouldReject: true, -> - cmd = "echo 'bad' >&2 && exit 2" - errorOutput = '' - options = - stderr: (data) -> - errorOutput += data - ChildProcess.exec(cmd, options).fail (error) -> - expect(error.exitStatus).toBe 2 - expect(errorOutput).toBe "bad\n" - - describe "when a command returns a large amount of data (over 10k)", -> - originalTimeout = null - beforeEach -> - originalTimeout = jasmine.getEnv().defaultTimeoutInterval - jasmine.getEnv().defaultTimeoutInterval = 1000 - - afterEach -> - jasmine.getEnv().defaultTimeoutInterval = originalTimeout - - it "does not block indefinitely on stdout or stderr callbacks (regression)", -> - output = [] - - waitsForPromise -> - cmd = "for i in {1..20000}; do echo $RANDOM; done" - options = - stdout: (data) -> output.push(data) - stderr: (data) -> - - ChildProcess.exec(cmd, options) - - runs -> - expect(output.length).toBeGreaterThan 1 - - describe "when the cwd option is set", -> - it "runs the task from the specified current working directory", -> - output = [] - - waitsForPromise -> - options = - cwd: "/Applications" - stdout: (data) -> output.push(data) - stderr: (data) -> - - ChildProcess.exec("pwd", options) - - runs -> - expect(output.join('')).toBe "/Applications\n" diff --git a/spec/stdlib/cson-spec.coffee b/spec/stdlib/cson-spec.coffee index a1207203c..0171cebfb 100644 --- a/spec/stdlib/cson-spec.coffee +++ b/spec/stdlib/cson-spec.coffee @@ -85,6 +85,6 @@ describe "CSON", -> singleTrailingNewline: true cson = CSON.stringify(object) - {CoffeeScript} = require 'coffee-script' + CoffeeScript = require 'coffee-script' evaledObject = CoffeeScript.eval(cson, bare: true) expect(evaledObject).toEqual object diff --git a/spec/stdlib/fs-spec.coffee b/spec/stdlib/fs-utils-spec.coffee similarity index 62% rename from spec/stdlib/fs-spec.coffee rename to spec/stdlib/fs-utils-spec.coffee index 94445d011..1e214e1dc 100644 --- a/spec/stdlib/fs-spec.coffee +++ b/spec/stdlib/fs-utils-spec.coffee @@ -1,4 +1,4 @@ -fs = require 'fs' +fs = require 'fs-utils' describe "fs", -> describe ".read(path)", -> @@ -9,7 +9,7 @@ describe "fs", -> expect(-> fs.read(require.resolve("fixtures/binary-file.png"))).not.toThrow() describe ".isFile(path)", -> - fixturesDir = require.resolve('fixtures') + fixturesDir = fs.resolveOnLoadPath('fixtures') it "returns true with a file path", -> expect(fs.isFile(fs.join(fixturesDir, 'sample.js'))).toBe true @@ -24,7 +24,7 @@ describe "fs", -> describe ".directory(path)", -> describe "when called with a file path", -> it "returns the path to the directory", -> - expect(fs.directory(require.resolve('fixtures/dir/a'))).toBe require.resolve('fixtures/dir') + expect(fs.directory(fs.resolveOnLoadPath('fixtures/dir/a'))).toBe fs.resolveOnLoadPath('fixtures/dir') describe "when called with a directory path", -> it "return the path it was given", -> @@ -42,10 +42,10 @@ describe "fs", -> describe ".exists(path)", -> it "returns true when path exsits", -> - expect(fs.exists(require.resolve('fixtures'))).toBe true + expect(fs.exists(fs.resolveOnLoadPath('fixtures'))).toBe true it "returns false when path doesn't exsit", -> - expect(fs.exists(require.resolve("fixtures") + "/-nope-does-not-exist")).toBe false + expect(fs.exists(fs.resolveOnLoadPath("fixtures") + "/-nope-does-not-exist")).toBe false expect(fs.exists("")).toBe false expect(fs.exists(null)).toBe false @@ -77,18 +77,18 @@ describe "fs", -> fs.makeTree("/tmp/a/b/c") expect(fs.exists("/tmp/a/b/c")).toBeTruthy() - describe ".traverseTree(path, onFile, onDirectory)", -> + describe ".traverseTreeSync(path, onFile, onDirectory)", -> fixturesDir = null beforeEach -> - fixturesDir = require.resolve('fixtures') + fixturesDir = fs.resolveOnLoadPath('fixtures') it "calls fn for every path in the tree at the given path", -> paths = [] onPath = (path) -> paths.push(path) true - fs.traverseTree fixturesDir, onPath, onPath + fs.traverseTreeSync fixturesDir, onPath, onPath expect(paths).toEqual fs.listTree(fixturesDir) it "does not recurse into a directory if it is pruned", -> @@ -99,7 +99,7 @@ describe "fs", -> else paths.push(path) true - fs.traverseTree fixturesDir, onPath, onPath + fs.traverseTreeSync fixturesDir, onPath, onPath expect(paths.length).toBeGreaterThan 0 for path in paths @@ -114,24 +114,51 @@ describe "fs", -> paths = [] onPath = (path) -> paths.push(path.substring(regularPath.length + 1)) - fs.traverseTree(symlinkPath, onSymlinkPath, onSymlinkPath) - fs.traverseTree(regularPath, onPath, onPath) + fs.traverseTreeSync(symlinkPath, onSymlinkPath, onSymlinkPath) + fs.traverseTreeSync(regularPath, onPath, onPath) expect(symlinkPaths).toEqual(paths) - describe ".lastModified(path)", -> - it "returns a Date object representing the time the file was last modified", -> - beforeWrite = new Date - fs.write('/tmp/foo', '') - lastModified = fs.lastModified('/tmp/foo') - expect(lastModified instanceof Date).toBeTruthy() - expect(lastModified.getTime()).toBeGreaterThan(beforeWrite.getTime() - 1000) - describe ".md5ForPath(path)", -> it "returns the MD5 hash of the file at the given path", -> expect(fs.md5ForPath(require.resolve('fixtures/sample.js'))).toBe 'dd38087d0d7e3e4802a6d3f9b9745f2b' describe ".list(path, extensions)", -> - it "returns the paths with the specified extensions", -> - path = require.resolve('fixtures/css.css') - expect(fs.list(require.resolve('fixtures'), ['.css'])).toEqual [path] + it "returns the absolute paths of entries within the given directory", -> + paths = fs.list(project.getPath()) + expect(paths).toContain project.resolve('css.css') + expect(paths).toContain project.resolve('coffee.coffee') + expect(paths).toContain project.resolve('two-hundred.txt') + + it "returns undefined for paths that aren't directories or don't exist", -> + expect(fs.list(project.resolve('sample.js'))).toBeUndefined() + expect(fs.list('/non/existent/directory')).toBeUndefined() + + it "can filter the paths by an optional array of file extensions", -> + paths = fs.list(project.getPath(), ['.css', 'coffee']) + expect(paths).toContain project.resolve('css.css') + expect(paths).toContain project.resolve('coffee.coffee') + expect(path).toMatch /(css|coffee)$/ for path in paths + + describe ".listAsync(path, [extensions,] callback)", -> + paths = null + + it "calls the callback with the absolute paths of entries within the given directory", -> + waitsFor (done) -> + fs.listAsync project.getPath(), (err, result) -> + paths = result + done() + runs -> + expect(paths).toContain project.resolve('css.css') + expect(paths).toContain project.resolve('coffee.coffee') + expect(paths).toContain project.resolve('two-hundred.txt') + + it "can filter the paths by an optional array of file extensions", -> + waitsFor (done) -> + fs.listAsync project.getPath(), ['css', '.coffee'], (err, result) -> + paths = result + done() + runs -> + expect(paths).toContain project.resolve('css.css') + expect(paths).toContain project.resolve('coffee.coffee') + expect(path).toMatch /(css|coffee)$/ for path in paths diff --git a/spec/stdlib/jquery-extensions-spec.coffee b/spec/stdlib/jquery-extensions-spec.coffee index 4bdd8fd11..b803de4f1 100644 --- a/spec/stdlib/jquery-extensions-spec.coffee +++ b/spec/stdlib/jquery-extensions-spec.coffee @@ -42,7 +42,7 @@ describe 'jQuery extensions', -> element.trigger 'foo' expect(events).toEqual [2,1,3] - describe "$.fn.events() and $.fn.document", -> + describe "$.fn.events() and $.fn.document(...)", -> it "returns a list of all events being listened for on the target node or its ancestors, along with their documentation string", -> view = $$ -> @div id: 'a', => @@ -50,20 +50,18 @@ describe 'jQuery extensions', -> @div id: 'c' @div id: 'd' - view.document - 'a1': "This is event A2" - 'b2': "This is event b2" + view.document 'a1', "This is event A2" + view.document 'b2', "This is event b2" - view.document 'a1': "A1: Waste perfectly-good steak" + view.document 'a1', "A1: Waste perfectly-good steak" view.on 'a1', -> view.on 'a2', -> view.on 'b1', -> # should not appear as a duplicate divB = view.find('#b') - divB.document - 'b1': "B1: Super-sonic bomber" - 'b2': "B2: Looks evil. Kinda is." + divB.document 'b1', "B1: Super-sonic bomber" + divB.document 'b2', "B2: Looks evil. Kinda is." divB.on 'b1', -> divB.on 'b2', -> @@ -77,6 +75,51 @@ describe 'jQuery extensions', -> 'a1': "A1: Waste perfectly-good steak" 'a2': null + describe "$.fn.command(eventName, [selector, options,] handler)", -> + [view, handler] = [] + + beforeEach -> + view = $$ -> + @div class: 'a', => + @div class: 'b' + @div class: 'c' + handler = jasmine.createSpy("commandHandler") + + it "binds the handler to the given event / selector for all argument combinations", -> + view.command 'test:foo', handler + view.trigger 'test:foo' + expect(handler).toHaveBeenCalled() + handler.reset() + + view.command 'test:bar', '.b', handler + view.find('.b').trigger 'test:bar' + view.find('.c').trigger 'test:bar' + expect(handler.callCount).toBe 1 + handler.reset() + + view.command 'test:baz', doc: 'Spaz', handler + view.trigger 'test:baz' + expect(handler).toHaveBeenCalled() + handler.reset() + + view.command 'test:quux', '.c', doc: 'Lorem', handler + view.find('.b').trigger 'test:quux' + view.find('.c').trigger 'test:quux' + expect(handler.callCount).toBe 1 + + it "passes the 'data' option through when binding the event handler", -> + view.command 'test:foo', data: "bar", handler + view.trigger 'test:foo' + expect(handler.argsForCall[0][0].data).toBe 'bar' + + it "sets a custom docstring if the 'doc' option is specified", -> + view.command 'test:foo', doc: "Foo!", handler + expect(view.events()).toEqual 'test:foo': 'Test: Foo!' + + it "capitalizes the 'github' prefix how we like it", -> + view.command 'github:spelling', handler + expect(view.events()).toEqual 'github:spelling': 'GitHub: Spelling' + describe "$.fn.scrollUp/Down/ToTop/ToBottom", -> it "scrolls the element in the specified way if possible", -> view = $$ -> @div => _.times 20, => @div('A') diff --git a/spec/stdlib/onig-reg-exp-spec.coffee b/spec/stdlib/onig-reg-exp-spec.coffee index 7f43d47c7..5f0b9c87d 100644 --- a/spec/stdlib/onig-reg-exp-spec.coffee +++ b/spec/stdlib/onig-reg-exp-spec.coffee @@ -1,15 +1,15 @@ -OnigRegExp = require 'onig-reg-exp' +{OnigRegExp} = require 'oniguruma' describe "OnigRegExp", -> describe ".search(string, index)", -> it "returns an array of the match and all capture groups", -> - regex = OnigRegExp.create("\\w(\\d+)") + regex = new OnigRegExp("\\w(\\d+)") result = regex.search("----a123----") expect(result).toEqual ["a123", "123"] expect(result.index).toBe 4 expect(result.indices).toEqual [4, 5] it "returns null if it does not match", -> - regex = OnigRegExp.create("\\w(\\d+)") + regex = new OnigRegExp("\\w(\\d+)") result = regex.search("--------") expect(result).toBeNull() diff --git a/spec/stdlib/task-shell-spec.coffee b/spec/stdlib/task-shell-spec.coffee index d1ccb8fc0..f1a539036 100644 --- a/spec/stdlib/task-shell-spec.coffee +++ b/spec/stdlib/task-shell-spec.coffee @@ -2,7 +2,7 @@ Task = require 'task' describe "Task shell", -> describe "populating the window with fake properties", -> - describe "when jQuery is loaded in a web worker", -> + describe "when jQuery is loaded in a child process", -> it "doesn't log to the console", -> spyOn(console, 'log') spyOn(console, 'error') @@ -14,7 +14,7 @@ describe "Task shell", -> task = new JQueryTask() task.start() - waitsFor "web worker to start and jquery to be required", 5000, -> + waitsFor "child process to start and jquery to be required", 5000, -> task.jqueryLoaded runs -> expect(task.jqueryLoaded).toBeTruthy() diff --git a/src/app/atom-package.coffee b/src/app/atom-package.coffee index 8a0e312c9..c7f5cfeb3 100644 --- a/src/app/atom-package.coffee +++ b/src/app/atom-package.coffee @@ -1,20 +1,29 @@ +TextMateGrammar = require 'text-mate-grammar' Package = require 'package' -fs = require 'fs' +fsUtils = require 'fs-utils' _ = require 'underscore' $ = require 'jquery' +CSON = require 'cson' module.exports = class AtomPackage extends Package metadata: null + keymaps: null + stylesheets: null + grammars: null + scopedProperties: null + mainModulePath: null + resolvedMainModulePath: false mainModule: null - deferActivation: false load: -> try @loadMetadata() @loadKeymaps() @loadStylesheets() - if @deferActivation = @metadata.activationEvents? + @loadGrammars() + @loadScopedProperties() + if @metadata.activationEvents? @registerDeferredDeserializers() else @requireMainModule() @@ -22,43 +31,91 @@ class AtomPackage extends Package console.warn "Failed to load package named '#{@name}'", e.stack this + activate: ({immediate}={}) -> + keymap.add(path, map) for [path, map] in @keymaps + applyStylesheet(path, content) for [path, content] in @stylesheets + syntax.addGrammar(grammar) for grammar in @grammars + syntax.addProperties(path, selector, properties) for [path, selector, properties] in @scopedProperties + + if @metadata.activationEvents? and not immediate + @subscribeToActivationEvents() + else + @activateNow() + + activateNow: -> + try + if @requireMainModule() + config.setDefaults(@name, @mainModule.configDefaults) + @mainModule.activate(atom.getPackageState(@name) ? {}) + catch e + console.warn "Failed to activate package named '#{@name}'", e.stack + loadMetadata: -> - if metadataPath = fs.resolveExtension(fs.join(@path, 'package'), ['cson', 'json']) - @metadata = fs.readObject(metadataPath) + if metadataPath = fsUtils.resolveExtension(fsUtils.join(@path, 'package'), ['cson', 'json']) + @metadata = CSON.readObject(metadataPath) @metadata ?= {} loadKeymaps: -> - keymapsDirPath = fs.join(@path, 'keymaps') + @keymaps = @getKeymapPaths().map (path) -> [path, CSON.readObject(path)] + getKeymapPaths: -> + keymapsDirPath = fsUtils.join(@path, 'keymaps') if @metadata.keymaps - for path in @metadata.keymaps - keymapPath = fs.resolve(keymapsDirPath, path, ['cson', 'json', '']) - keymap.load(keymapPath) + @metadata.keymaps.map (name) -> fsUtils.resolve(keymapsDirPath, name, ['cson', 'json', '']) else - keymap.loadDirectory(keymapsDirPath) + fsUtils.list(keymapsDirPath, ['cson', 'json']) ? [] loadStylesheets: -> - stylesheetDirPath = fs.join(@path, 'stylesheets') - for stylesheetPath in fs.list(stylesheetDirPath) - requireStylesheet(stylesheetPath) + @stylesheets = @getStylesheetPaths().map (path) -> [path, loadStylesheet(path)] - activate: -> - if @deferActivation - @subscribeToActivationEvents() + getStylesheetPaths: -> + stylesheetDirPath = fsUtils.join(@path, 'stylesheets') + if @metadata.stylesheets + @metadata.stylesheets.map (name) -> fsUtils.resolve(stylesheetDirPath, name, ['css', 'less', '']) else - try - if @requireMainModule() - config.setDefaults(@name, @mainModule.configDefaults) - atom.activateAtomPackage(this) - catch e - console.warn "Failed to activate package named '#{@name}'", e.stack + fsUtils.list(stylesheetDirPath, ['css', 'less']) ? [] + + loadGrammars: -> + @grammars = [] + grammarsDirPath = fsUtils.join(@path, 'grammars') + for grammarPath in fsUtils.list(grammarsDirPath, ['.cson', '.json']) ? [] + @grammars.push(TextMateGrammar.loadSync(grammarPath)) + + loadScopedProperties: -> + @scopedProperties = [] + scopedPropertiessDirPath = fsUtils.join(@path, 'scoped-properties') + for scopedPropertiesPath in fsUtils.list(scopedPropertiessDirPath, ['.cson', '.json']) ? [] + for selector, properties of fsUtils.readObject(scopedPropertiesPath) + @scopedProperties.push([scopedPropertiesPath, selector, properties]) + + serialize: -> + try + @mainModule?.serialize?() + catch e + console.error "Error serializing package '#{@name}'", e.stack + + deactivate: -> + @unsubscribeFromActivationEvents() + syntax.removeGrammar(grammar) for grammar in @grammars + syntax.removeProperties(path) for [path] in @scopedProperties + keymap.remove(path) for [path] in @keymaps + removeStylesheet(path) for [path] in @stylesheets + @mainModule?.deactivate?() requireMainModule: -> return @mainModule if @mainModule - mainPath = @path - mainPath = fs.join(mainPath, @metadata.main) if @metadata.main - mainPath = require.resolve(mainPath) - @mainModule = require(mainPath) if fs.isFile(mainPath) + mainModulePath = @getMainModulePath() + @mainModule = require(mainModulePath) if fsUtils.isFile(mainModulePath) + + getMainModulePath: -> + return @mainModulePath if @resolvedMainModulePath + @resolvedMainModulePath = true + mainModulePath = + if @metadata.main + fsUtils.join(@path, @metadata.main) + else + fsUtils.join(@path, 'index') + @mainModulePath = fsUtils.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...]) registerDeferredDeserializers: -> for deserializerName in @metadata.deferredDeserializers ? [] @@ -66,25 +123,23 @@ class AtomPackage extends Package subscribeToActivationEvents: () -> return unless @metadata.activationEvents? - - activateHandler = (event) => - bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event) - @deferActivation = false - @activate() - $(event.target).trigger(event) - @restoreEventHandlersOnBubblePath(bubblePathEventHandlers) - @unsubscribeFromActivationEvents(activateHandler) - if _.isArray(@metadata.activationEvents) - rootView.command(event, activateHandler) for event in @metadata.activationEvents + rootView.command(event, @handleActivationEvent) for event in @metadata.activationEvents else - rootView.command(event, selector, activateHandler) for event, selector of @metadata.activationEvents + rootView.command(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents - unsubscribeFromActivationEvents: (activateHandler) -> + handleActivationEvent: (event) => + bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event) + @activateNow() + $(event.target).trigger(event) + @restoreEventHandlersOnBubblePath(bubblePathEventHandlers) + @unsubscribeFromActivationEvents() + + unsubscribeFromActivationEvents: -> if _.isArray(@metadata.activationEvents) - rootView.off(event, activateHandler) for event in @metadata.activationEvents + rootView.off(event, @handleActivationEvent) for event in @metadata.activationEvents else - rootView.off(event, selector, activateHandler) for event, selector of @metadata.activationEvents + rootView.off(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents disableEventHandlersOnBubblePath: (event) -> bubblePathEventHandlers = [] diff --git a/src/app/atom-theme.coffee b/src/app/atom-theme.coffee index 04563b3c7..06f765118 100644 --- a/src/app/atom-theme.coffee +++ b/src/app/atom-theme.coffee @@ -1,5 +1,6 @@ -fs = require 'fs' +fs = require 'fs-utils' Theme = require 'theme' +CSON = require 'cson' module.exports = class AtomTheme extends Theme @@ -13,7 +14,7 @@ class AtomTheme extends Theme else metadataPath = fs.resolveExtension(fs.join(@path, 'package'), ['cson', 'json']) if fs.isFile(metadataPath) - stylesheetNames = fs.readObject(metadataPath)?.stylesheets + stylesheetNames = CSON.readObject(metadataPath)?.stylesheets if stylesheetNames @loadStylesheet(fs.join(@path, name)) for name in stylesheetNames else diff --git a/src/app/atom.coffee b/src/app/atom.coffee index 315f8314e..70c05a952 100644 --- a/src/app/atom.coffee +++ b/src/app/atom.coffee @@ -1,9 +1,8 @@ -fs = require 'fs' +fs = require 'fs-utils' _ = require 'underscore' Package = require 'package' TextMatePackage = require 'text-mate-package' Theme = require 'theme' -LoadTextMatePackagesTask = require 'load-text-mate-packages-task' messageIdCounter = 1 originalSendMessageToBrowserProcess = atom.sendMessageToBrowserProcess @@ -14,70 +13,91 @@ _.extend atom, loadedThemes: [] pendingBrowserProcessCallbacks: {} loadedPackages: [] - activatedAtomPackages: [] - atomPackageStates: {} + activePackages: [] + packageStates: {} presentingModal: false pendingModals: [[]] getPathToOpen: -> @getWindowState('pathToOpen') ? window.location.params.pathToOpen - activateAtomPackage: (pack) -> - @activatedAtomPackages.push(pack) - pack.mainModule.activate(@atomPackageStates[pack.name] ? {}) + getPackageState: (name) -> + @packageStates[name] - deactivateAtomPackages: -> - pack.mainModule.deactivate?() for pack in @activatedAtomPackages - @activatedAtomPackages = [] - - serializeAtomPackages: -> - packageStates = {} - for pack in @loadedPackages - if pack in @activatedAtomPackages - try - packageStates[pack.name] = pack.mainModule.serialize?() - catch e - console?.error("Exception serializing '#{pack.name}' package's module\n", e.stack) - else - packageStates[pack.name] = @atomPackageStates[pack.name] - packageStates - - loadTextPackage: -> - textPackagePath = _.find @getPackagePaths(), (path) -> fs.base(path) is 'text.tmbundle' - pack = Package.build(textPackagePath) - @loadedPackages.push(pack) - pack.load() - - loadPackages: -> - textMatePackages = [] - paths = @getPackagePaths().filter (path) -> fs.base(path) isnt 'text.tmbundle' - for path in paths - pack = Package.build(path) - @loadedPackages.push(pack) - if pack instanceof TextMatePackage - textMatePackages.push(pack) - else - pack.load() - - new LoadTextMatePackagesTask(textMatePackages).start() if textMatePackages.length > 0 + setPackageState: (name, state) -> + @packageStates[name] = state activatePackages: -> - pack.activate() for pack in @loadedPackages + @activatePackage(pack.path) for pack in @getLoadedPackages() + + activatePackage: (id, options) -> + if pack = @loadPackage(id, options) + @activePackages.push(pack) + pack.activate(options) + pack + + deactivatePackages: -> + @deactivatePackage(pack.path) for pack in @getActivePackages() + + deactivatePackage: (id) -> + if pack = @getActivePackage(id) + @setPackageState(pack.name, state) if state = pack.serialize?() + pack.deactivate() + _.remove(@activePackages, pack) + else + throw new Error("No active package for id '#{id}'") + + getActivePackage: (id) -> + if path = @resolvePackagePath(id) + _.detect @activePackages, (pack) -> pack.path is path + + isPackageActive: (id) -> + if path = @resolvePackagePath(id) + _.detect @activePackages, (pack) -> pack.path is path + + getActivePackages: -> + _.clone(@activePackages) + + loadPackages: -> + @loadPackage(path) for path in @getPackagePaths() when not @isPackageDisabled(path) + + loadPackage: (id, options) -> + if @isPackageDisabled(id) + return console.warn("Tried to load disabled packaged '#{id}'") + + if path = @resolvePackagePath(id) + return pack if pack = @getLoadedPackage(id) + pack = Package.load(path, options) + @loadedPackages.push(pack) + pack + else + throw new Error("Could not resolve '#{id}' to a package path") + + resolvePackagePath: _.memoize (id) -> + return id if fs.isDirectory(id) + path = fs.resolve(config.packageDirPaths..., id) + path if fs.isDirectory(path) + + getLoadedPackage: (id) -> + if path = @resolvePackagePath(id) + _.detect @loadedPackages, (pack) -> pack.path is path + + isPackageLoaded: (id) -> + @getLoadedPackage(id)? getLoadedPackages: -> _.clone(@loadedPackages) + isPackageDisabled: (id) -> + if path = @resolvePackagePath(id) + _.include(config.get('core.disabledPackages') ? [], fs.base(path)) + getPackagePaths: -> - disabledPackages = config.get("core.disabledPackages") ? [] packagePaths = [] for packageDirPath in config.packageDirPaths for packagePath in fs.list(packageDirPath) - continue if not fs.isDirectory(packagePath) - continue if fs.base(packagePath) in disabledPackages - continue if packagePath in packagePaths - packagePaths.push(packagePath) - - packagePaths + packagePaths.push(packagePath) if fs.isDirectory(packagePath) + _.uniq(packagePaths) loadThemes: -> themeNames = config.get("core.themes") ? ['atom-dark-ui', 'atom-dark-syntax'] @@ -179,17 +199,6 @@ _.extend atom, toggleFullScreen: -> @sendMessageToBrowserProcess('toggleFullScreen') - getRootViewStateForPath: (path) -> - if json = localStorage[path] - JSON.parse(json) - - setRootViewStateForPath: (path, state) -> - return unless path - if state? - localStorage[path] = JSON.stringify(state) - else - delete localStorage[path] - sendMessageToBrowserProcess: (name, data=[], callbacks) -> messageId = messageIdCounter++ data.unshift(messageId) @@ -209,12 +218,25 @@ _.extend atom, windowState getWindowState: (keyPath) -> - windowState = JSON.parse($native.getWindowState()) + windowState = JSON.parse(@getInMemoryWindowState() ? @getSavedWindowState() ? '{}') if keyPath _.valueForKeyPath(windowState, keyPath) else windowState + getInMemoryWindowState: -> + inMemoryState = $native.getWindowState() + if inMemoryState.length > 0 + inMemoryState + else + null + + getSavedWindowState: -> + localStorage[window.location.params.pathToOpen] + + saveWindowState: -> + localStorage[@getPathToOpen()] = JSON.stringify(@getWindowState()) + update: -> @sendMessageToBrowserProcess('update') diff --git a/src/app/binding-set.coffee b/src/app/binding-set.coffee index 168de6bbe..3bf87dab8 100644 --- a/src/app/binding-set.coffee +++ b/src/app/binding-set.coffee @@ -1,6 +1,6 @@ $ = require 'jquery' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' Specificity = require 'specificity' PEG = require 'pegjs' @@ -14,8 +14,9 @@ class BindingSet commandsByKeystrokes: null commandForEvent: null parser: null + name: null - constructor: (@selector, commandsByKeystrokes, @index) -> + constructor: (@selector, commandsByKeystrokes, @index, @name) -> BindingSet.parser ?= PEG.buildParser(fs.read(require.resolve 'keystroke-pattern.pegjs')) @specificity = Specificity(@selector) @commandsByKeystrokes = @normalizeCommandsByKeystrokes(commandsByKeystrokes) diff --git a/src/app/config.coffee b/src/app/config.coffee index dc79df9ee..c8d36db6e 100644 --- a/src/app/config.coffee +++ b/src/app/config.coffee @@ -1,6 +1,7 @@ -fs = require 'fs' +fs = require 'fs-utils' _ = require 'underscore' EventEmitter = require 'event-emitter' +CSON = require 'cson' configDirPath = fs.absolute("~/.atom") bundledPackagesDirPath = fs.join(resourcePath, "src/packages") @@ -10,8 +11,6 @@ vendoredThemesDirPath = fs.join(resourcePath, "vendor/themes") userThemesDirPath = fs.join(configDirPath, "themes") userPackagesDirPath = fs.join(configDirPath, "packages") -require.paths.unshift userPackagesDirPath - module.exports = class Config configDirPath: configDirPath @@ -36,19 +35,18 @@ class Config fs.makeDirectory(@configDirPath) templateConfigDirPath = fs.resolve(window.resourcePath, 'dot-atom') - onConfigDirFile = (path) => relativePath = path.substring(templateConfigDirPath.length + 1) configPath = fs.join(@configDirPath, relativePath) fs.write(configPath, fs.read(path)) - fs.traverseTree(templateConfigDirPath, onConfigDirFile, (path) -> true) + fs.traverseTreeSync(templateConfigDirPath, onConfigDirFile, (path) -> true) configThemeDirPath = fs.join(@configDirPath, 'themes') onThemeDirFile = (path) -> relativePath = path.substring(bundledThemesDirPath.length + 1) configPath = fs.join(configThemeDirPath, relativePath) fs.write(configPath, fs.read(path)) - fs.traverseTree(bundledThemesDirPath, onThemeDirFile, (path) -> true) + fs.traverseTreeSync(bundledThemesDirPath, onThemeDirFile, (path) -> true) load: -> @initializeConfigDirectory() @@ -57,7 +55,7 @@ class Config loadUserConfig: -> if fs.exists(@configFilePath) try - userConfig = fs.readObject(@configFilePath) + userConfig = CSON.readObject(@configFilePath) _.extend(@settings, userConfig) catch e @configFileHasErrors = true @@ -103,6 +101,6 @@ class Config @trigger 'updated' save: -> - fs.writeObject(@configFilePath, @settings) + CSON.writeObject(@configFilePath, @settings) _.extend Config.prototype, EventEmitter diff --git a/src/app/directory.coffee b/src/app/directory.coffee index 808e839e7..d73612fb0 100644 --- a/src/app/directory.coffee +++ b/src/app/directory.coffee @@ -1,5 +1,6 @@ _ = require 'underscore' fs = require 'fs' +fsUtils = require 'fs-utils' File = require 'file' EventEmitter = require 'event-emitter' @@ -7,23 +8,27 @@ module.exports = class Directory path: null - constructor: (@path) -> + constructor: (@path, @symlink=false) -> getBaseName: -> - fs.base(@path) + fsUtils.base(@path) getPath: -> @path getEntries: -> directories = [] files = [] - for path in fs.list(@path) - if fs.isDirectory(path) - directories.push(new Directory(path)) - else if fs.isFile(path) - files.push(new File(path)) - else - console.error "#{path} is neither a file nor a directory." + for path in fsUtils.list(@path) + try + stat = fs.lstatSync(path) + symlink = stat.isSymbolicLink() + stat = fs.statSync(path) if symlink + catch e + continue + if stat.isDirectory() + directories.push(new Directory(path, symlink)) + else if stat.isFile() + files.push(new File(path, symlink)) directories.concat(files) @@ -34,10 +39,12 @@ class Directory @unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0 subscribeToNativeChangeEvents: -> - @watchId = $native.watchPath @path, (eventType) => + @watchSubscription = fsUtils.watchPath @path, (eventType) => @trigger "contents-changed" if eventType is "contents-change" unsubscribeFromNativeChangeEvents: -> - $native.unwatchPath(@path, @watchId) + if @watchSubscription? + @watchSubscription.unwatch() + @watchSubscription = null _.extend Directory.prototype, EventEmitter diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 0104a297f..e14baa16a 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -1,5 +1,5 @@ Point = require 'point' -Buffer = require 'buffer' +Buffer = require 'text-buffer' LanguageMode = require 'language-mode' DisplayBuffer = require 'display-buffer' Cursor = require 'cursor' @@ -8,7 +8,7 @@ EventEmitter = require 'event-emitter' Subscriber = require 'subscriber' Range = require 'range' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' module.exports = class EditSession @@ -25,11 +25,6 @@ class EditSession session.setCursorScreenPosition(state.cursorScreenPosition) session - @identifiedBy: 'path' - - @deserializesToSameObject: (state, editSession) -> - state.path - scrollTop: 0 scrollLeft: 0 languageMode: null @@ -589,9 +584,15 @@ class EditSession cursor = @addCursor(marker) selection = new Selection({editSession: this, marker, cursor}) @selections.push(selection) + selectionBufferRange = selection.getBufferRange() @mergeIntersectingSelections() - @trigger 'selection-added', selection - selection + if selection.destroyed + for selection in @getSelections() + if selection.intersectsBufferRange(selectionBufferRange) + return selection + else + @trigger 'selection-added', selection + selection addSelectionForBufferRange: (bufferRange, options={}) -> options = _.defaults({invalidationStrategy: 'never'}, options) @@ -842,11 +843,18 @@ class EditSession getGrammar: -> @languageMode.grammar + setGrammar: (grammar) -> + @languageMode.grammar = grammar + @handleGrammarChange() + reloadGrammar: -> - if @languageMode.reloadGrammar() - @unfoldAll() - @displayBuffer.tokenizedBuffer.resetScreenLines() - true + @handleGrammarChange() if @languageMode.reloadGrammar() + + handleGrammarChange: -> + @unfoldAll() + @displayBuffer.tokenizedBuffer.resetScreenLines() + @trigger 'grammar-changed' + true getDebugSnapshot: -> [ diff --git a/src/app/editor.coffee b/src/app/editor.coffee index a8380d7af..9377de760 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -1,12 +1,12 @@ {View, $$} = require 'space-pen' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Gutter = require 'gutter' Point = require 'point' Range = require 'range' EditSession = require 'edit-session' CursorView = require 'cursor-view' SelectionView = require 'selection-view' -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' _ = require 'underscore' @@ -16,6 +16,7 @@ class Editor extends View fontSize: 20 showInvisibles: false showIndentGuide: false + showLineNumbers: true autoIndent: true autoIndentOnPaste: false nonWordCharacters: "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?-" @@ -61,7 +62,7 @@ class Editor extends View else {editSession, @mini} = (editSessionOrOptions ? {}) - requireStylesheet 'editor.less' + requireStylesheet 'editor' @id = Editor.nextEditorId++ @lineCache = [] @@ -149,13 +150,13 @@ class Editor extends View 'editor:toggle-line-comments': @toggleLineCommentsInSelection 'editor:log-cursor-scope': @logCursorScope 'editor:checkout-head-revision': @checkoutHead - 'editor:select-grammar': @selectGrammar 'editor:copy-path': @copyPathToPasteboard 'editor:move-line-up': @moveLineUp 'editor:move-line-down': @moveLineDown 'editor:duplicate-line': @duplicateLine 'editor:toggle-indent-guide': => config.set('editor.showIndentGuide', !config.get('editor.showIndentGuide')) 'editor:save-debug-snapshot': @saveDebugSnapshot + 'editor:toggle-line-numbers': => config.set('editor.showLineNumbers', !config.get('editor.showLineNumbers')) documentation = {} for name, method of editorBindings @@ -316,6 +317,7 @@ class Editor extends View backwardsScanInRange: (args...) -> @getBuffer().backwardsScanInRange(args...) configure: -> + @observeConfig 'editor.showLineNumbers', (showLineNumbers) => @gutter.setShowLineNumbers(showLineNumbers) @observeConfig 'editor.showInvisibles', (showInvisibles) => @setShowInvisibles(showInvisibles) @observeConfig 'editor.showIndentGuide', (showIndentGuide) => @setShowIndentGuide(showIndentGuide) @observeConfig 'editor.invisibles', (invisibles) => @setInvisibles(invisibles) @@ -371,7 +373,7 @@ class Editor extends View else if clickCount == 3 @activeEditSession.selectLine() unless e.shiftKey - @selectOnMousemoveUntilMouseup() + @selectOnMousemoveUntilMouseup() unless e.originalEvent.which > 1 @renderedLines.on 'mousedown', onMouseDown @@ -395,8 +397,6 @@ class Editor extends View e.pageX = @renderedLines.offset().left onMouseDown(e) - @subscribe syntax, 'grammars-loaded', => @reloadGrammar() - @scrollView.on 'scroll', => if @scrollView.scrollLeft() == 0 @gutter.removeClass('drop-shadow') @@ -456,6 +456,9 @@ class Editor extends View @reloadGrammar() @trigger 'editor:path-changed' + @activeEditSession.on "grammar-changed.editor", => + @trigger 'editor:grammar-changed' + @trigger 'editor:path-changed' @resetDisplay() @@ -586,6 +589,7 @@ class Editor extends View @setSoftWrapColumn(softWrapColumn) if @attached if @activeEditSession.getSoftWrap() @addClass 'soft-wrap' + @scrollView.scrollLeft(0) @_setSoftWrapColumn = => @setSoftWrapColumn() $(window).on "resize.editor-#{@id}", @_setSoftWrapColumn else @@ -635,19 +639,19 @@ class Editor extends View @requestDisplayUpdate() splitLeft: (items...) -> - @pane()?.splitLeft(items...).activeView + @getPane()?.splitLeft(items...).activeView splitRight: (items...) -> - @pane()?.splitRight(items...).activeView + @getPane()?.splitRight(items...).activeView splitUp: (items...) -> - @pane()?.splitUp(items...).activeView + @getPane()?.splitUp(items...).activeView splitDown: (items...) -> - @pane()?.splitDown(items...).activeView + @getPane()?.splitDown(items...).activeView - pane: -> - @closest('.pane').view() + getPane: -> + @parent('.item-views').parent('.pane').view() remove: (selector, keepData) -> return super if keepData or @removed @@ -655,7 +659,7 @@ class Editor extends View super rootView?.focus() - afterRemove: -> + beforeRemove: -> @removed = true @activeEditSession?.destroy() $(window).off(".editor-#{@id}") @@ -713,8 +717,6 @@ class Editor extends View fragment.remove() updateLayerDimensions: -> - @gutter.calculateWidth() - height = @lineHeight * @screenLineCount() unless @layerHeight == height @renderedLines.height(height) @@ -1141,20 +1143,23 @@ class Editor extends View else @highlightedLine = null - getGrammar: -> @activeEditSession.getGrammar() + getGrammar: -> + @activeEditSession.getGrammar() - selectGrammar: -> - GrammarView = require 'grammar-view' - new GrammarView(this) + setGrammar: (grammar) -> + throw new Error("Only mini-editors can explicity set their grammar") unless @mini + @activeEditSession.setGrammar(grammar) + @handleGrammarChange() reloadGrammar: -> - grammarChanged = @activeEditSession.reloadGrammar() - if grammarChanged - @clearRenderedLines() - @updateDisplay() - @trigger 'editor:grammar-changed' + grammarChanged = @activeEditSession.reloadGrammar() + @handleGrammarChange() if grammarChanged grammarChanged + handleGrammarChange: -> + @clearRenderedLines() + @updateDisplay() + bindToKeyedEvent: (key, event, callback) -> binding = {} binding[key] = event diff --git a/src/app/file.coffee b/src/app/file.coffee index 9edde198f..f982223b5 100644 --- a/src/app/file.coffee +++ b/src/app/file.coffee @@ -1,6 +1,7 @@ EventEmitter = require 'event-emitter' fs = require 'fs' +fsUtils = require 'fs-utils' _ = require 'underscore' module.exports = @@ -8,33 +9,34 @@ class File path: null cachedContents: null - constructor: (@path) -> - if @exists() and not fs.isFile(@path) - throw new Error(@path + " is a directory") + constructor: (@path, @symlink=false) -> + try + if fs.statSync(@path).isDirectory() + throw new Error("#{@path} is a directory") setPath: (@path) -> getPath: -> @path getBaseName: -> - fs.base(@path) + fsUtils.base(@path) write: (text) -> previouslyExisted = @exists() @cachedContents = text - fs.write(@getPath(), text) + fsUtils.write(@getPath(), text) @subscribeToNativeChangeEvents() if not previouslyExisted and @subscriptionCount() > 0 read: (flushCache)-> if not @exists() @cachedContents = null else if not @cachedContents? or flushCache - @cachedContents = fs.read(@getPath()) + @cachedContents = fsUtils.read(@getPath()) else @cachedContents exists: -> - fs.exists(@getPath()) + fsUtils.exists(@getPath()) afterSubscribe: -> @subscribeToNativeChangeEvents() if @exists() and @subscriptionCount() == 1 @@ -67,10 +69,12 @@ class File @trigger "removed" subscribeToNativeChangeEvents: -> - @watchId = $native.watchPath @path, (eventType, path) => + @watchSubscription = fsUtils.watchPath @path, (eventType, path) => @handleNativeChangeEvent(eventType, path) unsubscribeFromNativeChangeEvents: -> - $native.unwatchPath(@path, @watchId) + if @watchSubscription + @watchSubscription.unwatch() + @watchSubscription = null _.extend File.prototype, EventEmitter diff --git a/src/app/git.coffee b/src/app/git.coffee index b9f469b1c..21128dfbd 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -1,9 +1,9 @@ _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' Subscriber = require 'subscriber' EventEmitter = require 'event-emitter' -GitRepository = require 'git-repository' RepositoryStatusTask = require 'repository-status-task' +GitUtils = require 'git-utils' module.exports = class Git @@ -14,26 +14,18 @@ class Git catch e null - statusFlags: - index_new: 1 << 0 - index_modified: 1 << 1 - index_deleted: 1 << 2 - index_renamed: 1 << 3 - index_typechange: 1 << 4 - working_dir_new: 1 << 7 - working_dir_modified: 1 << 8 - working_dir_delete: 1 << 9 - working_dir_typechange: 1 << 10 - ignore: 1 << 14 - statuses: null upstream: null statusTask: null constructor: (path, options={}) -> + @repo = GitUtils.open(path) + unless @repo? + throw new Error("No Git repository found searching path: #{path}") + @statuses = {} @upstream = {ahead: 0, behind: 0} - @repo = GitRepository.open(path) + refreshOnWindowFocus = options.refreshOnWindowFocus ? true if refreshOnWindowFocus $ = require 'jquery' @@ -64,12 +56,14 @@ class Git @statusTask.off() @statusTask = null - @getRepo().destroy() - @repo = null + if @repo? + @repo.release() + @repo = null + @unsubscribe() getWorkingDirectory: -> - @getPath()?.replace(/\/\.git\/?$/, '') + @getRepo().getWorkingDirectory() getHead: -> @getRepo().getHead() ? '' @@ -88,22 +82,14 @@ class Git isPathIgnored: (path) -> @getRepo().isIgnored(@relativize(path)) - isStatusModified: (status=0) -> - modifiedFlags = @statusFlags.working_dir_modified | - @statusFlags.working_dir_delete | - @statusFlags.working_dir_typechange | - @statusFlags.index_modified | - @statusFlags.index_deleted | - @statusFlags.index_typechange - (status & modifiedFlags) > 0 + isStatusModified: (status) -> + @getRepo().isStatusModified(status) isPathModified: (path) -> @isStatusModified(@getPathStatus(path)) - isStatusNew: (status=0) -> - newFlags = @statusFlags.working_dir_new | - @statusFlags.index_new - (status & newFlags) > 0 + isStatusNew: (status) -> + @getRepo().isStatusNew(status) isPathNew: (path) -> @isStatusNew(@getPathStatus(path)) @@ -116,12 +102,7 @@ class Git path getShortHead: -> - head = @getHead() - return head.substring(11) if head.indexOf('refs/heads/') is 0 - return head.substring(10) if head.indexOf('refs/tags/') is 0 - return head.substring(13) if head.indexOf('refs/remotes/') is 0 - return head.substring(0, 7) if head.match(/[a-fA-F0-9]{40}/) - return head + @getRepo().getShortHead() checkoutHead: (path) -> headCheckedOut = @getRepo().checkoutHead(@relativize(path)) @@ -129,7 +110,7 @@ class Git headCheckedOut getDiffStats: (path) -> - @getRepo().getDiffStats(@relativize(path)) ? added: 0, deleted: 0 + @getRepo().getDiffStats(@relativize(path)) isSubmodule: (path) -> @getRepo().isSubmodule(@relativize(path)) @@ -154,10 +135,7 @@ class Git directoryStatus getAheadBehindCounts: -> - @getRepo().getAheadBehindCounts() ? ahead: 0, behind: 0 - - getLineDiffs: (path, text) -> - @getRepo().getLineDiffs(@relativize(path), text) ? [] + @getRepo().getAheadBehindCount() _.extend Git.prototype, Subscriber _.extend Git.prototype, EventEmitter diff --git a/src/app/gutter.coffee b/src/app/gutter.coffee index 19b46ca0c..2e19e09c6 100644 --- a/src/app/gutter.coffee +++ b/src/app/gutter.coffee @@ -1,5 +1,6 @@ {View, $$, $$$} = require 'space-pen' Range = require 'range' +_ = require 'underscore' module.exports = class Gutter extends View @@ -20,18 +21,11 @@ class Gutter extends View editor.on 'cursor:moved', highlightLines editor.on 'selection:changed', highlightLines - @calculateWidth() - editor: -> @parentView - calculateLineNumberPadding: -> - widthTesterElement = $$ -> @div {class: 'line-number'}, "" - widthTesterElement.width(0) - @append(widthTesterElement) - lineNumberPadding = widthTesterElement.outerWidth() - widthTesterElement.remove() - lineNumberPadding + setShowLineNumbers: (showLineNumbers) -> + if showLineNumbers then @lineNumbers.show() else @lineNumbers.hide() updateLineNumbers: (changes, renderFrom, renderTo) -> if renderFrom < @firstScreenRow or renderTo > @lastScreenRow @@ -48,6 +42,7 @@ class Gutter extends View renderLineNumbers: (startScreenRow, endScreenRow) -> editor = @editor() + maxDigits = editor.getLineCount().toString().length rows = editor.bufferRowsForScreenRows(startScreenRow, endScreenRow) cursorScreenRow = editor.getCursorScreenPosition().row @@ -56,25 +51,20 @@ class Gutter extends View if row == lastScreenRow rowValue = '•' else - rowValue = row + 1 + rowValue = (row + 1).toString() classes = ['line-number'] classes.push('fold') if editor.isFoldedAtBufferRow(row) - @div rowValue, class: classes.join(' ') + @div class: classes.join(' '), => + rowValuePadding = _.multiplyString(' ', maxDigits - rowValue.length) + @raw("#{rowValuePadding}#{rowValue}") + lastScreenRow = row - @calculateWidth() @firstScreenRow = startScreenRow @lastScreenRow = endScreenRow @highlightedRows = null @highlightLines() - calculateWidth: -> - highestNumberWidth = @editor().getLineCount().toString().length * @editor().charWidth - if highestNumberWidth != @highestNumberWidth - @highestNumberWidth = highestNumberWidth - @lineNumbers.width(highestNumberWidth + @calculateLineNumberPadding()) - @widthChanged?(@outerWidth()) - removeLineHighlights: -> return unless @highlightedLineNumbers for line in @highlightedLineNumbers diff --git a/src/app/keymap.coffee b/src/app/keymap.coffee index 695e733d1..71be30cec 100644 --- a/src/app/keymap.coffee +++ b/src/app/keymap.coffee @@ -1,12 +1,14 @@ $ = require 'jquery' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' +CSON = require 'cson' BindingSet = require 'binding-set' module.exports = class Keymap bindingSets: null + nextBindingSetIndex: 0 bindingSetsByFirstKeystroke: null queuedKeystrokes: null @@ -30,29 +32,48 @@ class Keymap $(document).command 'open-dev', => atom.openDev() loadBundledKeymaps: -> - @loadDirectory(require.resolve('keymaps')) + @loadDirectory(fs.resolveOnLoadPath('keymaps')) loadUserKeymaps: -> @loadDirectory(fs.join(config.configDirPath, 'keymaps')) loadDirectory: (directoryPath) -> - @load(filePath) for filePath in fs.list(directoryPath, ['.cson', '.json']) + @load(filePath) for filePath in fs.list(directoryPath, ['.cson', '.json']) ? [] load: (path) -> - @add(fs.readObject(path)) + @add(path, CSON.readObject(path)) - add: (keymap) -> + add: (args...) -> + name = args.shift() if args.length > 1 + keymap = args.shift() for selector, bindings of keymap - @bindKeys(selector, bindings) + @bindKeys(name, selector, bindings) - bindKeys: (selector, bindings) -> - bindingSet = new BindingSet(selector, bindings, @bindingSets.length) + remove: (name) -> + for bindingSet in @bindingSets.filter((bindingSet) -> bindingSet.name is name) + _.remove(@bindingSets, bindingSet) + for keystrokes of bindingSet.commandsByKeystrokes + keystroke = keystrokes.split(' ')[0] + _.remove(@bindingSetsByFirstKeystroke[keystroke], bindingSet) + + bindKeys: (args...) -> + name = args.shift() if args.length > 2 + [selector, bindings] = args + bindingSet = new BindingSet(selector, bindings, @nextBindingSetIndex++, name) @bindingSets.unshift(bindingSet) for keystrokes of bindingSet.commandsByKeystrokes keystroke = keystrokes.split(' ')[0] # only index by first keystroke @bindingSetsByFirstKeystroke[keystroke] ?= [] @bindingSetsByFirstKeystroke[keystroke].push(bindingSet) + unbindKeys: (selector, bindings) -> + bindingSet = _.detect @bindingSets, (bindingSet) -> + bindingSet.selector is selector and bindingSet.bindings is bindings + + if bindingSet + console.log "binding set", bindingSet + _.remove(@bindingSets, bindingSet) + bindingsForElement: (element) -> keystrokeMap = {} currentNode = $(element) diff --git a/src/app/keymaps/editor.cson b/src/app/keymaps/editor.cson index 8b192fece..f9675e6c1 100644 --- a/src/app/keymaps/editor.cson +++ b/src/app/keymaps/editor.cson @@ -20,7 +20,6 @@ 'meta-U': 'editor:lower-case' 'alt-meta-w': 'editor:close-other-edit-sessions' 'meta-P': 'editor:close-all-edit-sessions' - 'meta-L': 'editor:select-grammar' 'ctrl-C': 'editor:copy-path' 'ctrl-meta-up': 'editor:move-line-up' 'ctrl-meta-down': 'editor:move-line-down' diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee index 848ae826f..dc13fae18 100644 --- a/src/app/language-mode.coffee +++ b/src/app/language-mode.coffee @@ -1,7 +1,7 @@ Range = require 'range' _ = require 'underscore' require 'underscore-extensions' -OnigRegExp = require 'onig-reg-exp' +{OnigRegExp} = require 'oniguruma' module.exports = class LanguageMode @@ -17,10 +17,7 @@ class LanguageMode path = @buffer.getPath() pathContents = @buffer.cachedDiskContents previousGrammar = @grammar - if @buffer.project? - @grammar = @buffer.project.grammarForFilePath(path, pathContents) - else - @grammar = syntax.grammarForFilePath(path, pathContents) + @grammar = syntax.selectGrammar(path, pathContents) throw new Error("No grammar found for path: #{path}") unless @grammar previousGrammar isnt @grammar @@ -30,13 +27,13 @@ class LanguageMode buffer = @editSession.buffer commentStartRegexString = _.escapeRegExp(commentStartString).replace(/(\s+)$/, '($1)?') - commentStartRegex = OnigRegExp.create("^(\\s*)(#{commentStartRegexString})") + commentStartRegex = new OnigRegExp("^(\\s*)(#{commentStartRegexString})") shouldUncomment = commentStartRegex.test(buffer.lineForRow(start)) if commentEndString = syntax.getProperty(scopes, "editor.commentEnd") if shouldUncomment commentEndRegexString = _.escapeRegExp(commentEndString).replace(/^(\s+)/, '($1)?') - commentEndRegex = OnigRegExp.create("(#{commentEndRegexString})(\\s*)$") + commentEndRegex = new OnigRegExp("(#{commentEndRegexString})(\\s*)$") startMatch = commentStartRegex.search(buffer.lineForRow(start)) endMatch = commentEndRegex.search(buffer.lineForRow(end)) if startMatch and endMatch @@ -152,12 +149,12 @@ class LanguageMode increaseIndentRegexForScopes: (scopes) -> if increaseIndentPattern = syntax.getProperty(scopes, 'editor.increaseIndentPattern') - OnigRegExp.create(increaseIndentPattern) + new OnigRegExp(increaseIndentPattern) decreaseIndentRegexForScopes: (scopes) -> if decreaseIndentPattern = syntax.getProperty(scopes, 'editor.decreaseIndentPattern') - OnigRegExp.create(decreaseIndentPattern) + new OnigRegExp(decreaseIndentPattern) foldEndRegexForScopes: (scopes) -> if foldEndPattern = syntax.getProperty(scopes, 'editor.foldEndPattern') - OnigRegExp.create(foldEndPattern) + new OnigRegExp(foldEndPattern) diff --git a/src/app/load-text-mate-packages-handler.coffee b/src/app/load-text-mate-packages-handler.coffee deleted file mode 100644 index c6dd9a18a..000000000 --- a/src/app/load-text-mate-packages-handler.coffee +++ /dev/null @@ -1,5 +0,0 @@ -TextMatePackage = require 'text-mate-package' - -module.exports = - loadPackage: (path) -> - callTaskMethod('packageLoaded', new TextMatePackage(path).readGrammars()) diff --git a/src/app/load-text-mate-packages-task.coffee b/src/app/load-text-mate-packages-task.coffee deleted file mode 100644 index f2fef932c..000000000 --- a/src/app/load-text-mate-packages-task.coffee +++ /dev/null @@ -1,26 +0,0 @@ -Task = require 'task' - -module.exports = -class LoadTextMatePackagesTask extends Task - - constructor: (@packages) -> - super('load-text-mate-packages-handler') - - started: -> - @loadNextPackage() - - loadNextPackage: -> - unless @packages.length - @done() - syntax.trigger 'grammars-loaded' - return - - @package = @packages.shift() - @loadPackage(@package.path) - - loadPackage: (path) -> - @callWorkerMethod('loadPackage', path) - - packageLoaded: (grammars) -> - @package.loadGrammars(grammars) - @loadNextPackage() diff --git a/src/app/null-grammar.coffee b/src/app/null-grammar.coffee new file mode 100644 index 000000000..21c7877a2 --- /dev/null +++ b/src/app/null-grammar.coffee @@ -0,0 +1,9 @@ +Token = require 'token' + +module.exports = +class NullGrammar + name: 'Null Grammar' + scopeName: 'text.plain.null-grammar' + + tokenizeLine: (line) -> + { tokens: [new Token(value: line, scopes: ['null-grammar.text.plain'])] } diff --git a/src/app/package.coffee b/src/app/package.coffee index 5a7897347..c03e082d5 100644 --- a/src/app/package.coffee +++ b/src/app/package.coffee @@ -1,4 +1,4 @@ -fs = require 'fs' +fs = require 'fs-utils' module.exports = class Package @@ -11,6 +11,11 @@ class Package else new AtomPackage(path) + @load: (path, options) -> + pack = @build(path) + pack.load(options) + pack + name: null path: null diff --git a/src/app/pane.coffee b/src/app/pane.coffee index 3bd9c9f4c..e9132cc11 100644 --- a/src/app/pane.coffee +++ b/src/app/pane.coffee @@ -324,5 +324,5 @@ class Pane extends View container.adjustPaneDimensions() container.trigger 'pane:removed', [this] - afterRemove: -> + beforeRemove: -> item.destroy?() for item in @getItems() diff --git a/src/app/pasteboard.coffee b/src/app/pasteboard.coffee index 6349c0a10..404b48216 100644 --- a/src/app/pasteboard.coffee +++ b/src/app/pasteboard.coffee @@ -1,16 +1,19 @@ -{hex_md5} = require 'md5' +crypto = require 'crypto' module.exports = class Pasteboard signatureForMetadata: null + md5: (text) -> + crypto.createHash('md5').update(text, 'utf8').digest('hex') + write: (text, metadata) -> - @signatureForMetadata = hex_md5(text) + @signatureForMetadata = @md5(text) @metadata = metadata $native.writeToPasteboard(text) read: -> text = $native.readFromPasteboard() value = [text] - value.push(@metadata) if @signatureForMetadata == hex_md5(text) + value.push(@metadata) if @signatureForMetadata == @md5(text) value diff --git a/src/app/point.coffee b/src/app/point.coffee index e471ad6c6..6dd3eca27 100644 --- a/src/app/point.coffee +++ b/src/app/point.coffee @@ -1,10 +1,12 @@ +_ = require 'underscore' + module.exports = class Point @fromObject: (object) -> if object instanceof Point object else - if object instanceof Array + if _.isArray(object) [row, column] = object else { row, column } = object diff --git a/src/app/project.coffee b/src/app/project.coffee index f1a6f6634..53621f374 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -1,19 +1,19 @@ -fs = require 'fs' +fs = require 'fs-utils' _ = require 'underscore' $ = require 'jquery' Range = require 'range' -Buffer = require 'buffer' +Buffer = require 'text-buffer' EditSession = require 'edit-session' EventEmitter = require 'event-emitter' Directory = require 'directory' -ChildProcess = require 'child-process' +BufferedProcess = require 'buffered-process' module.exports = class Project registerDeserializer(this) @deserialize: (state) -> - new Project(state.path, state.grammarOverridesByPath) + new Project(state.path) tabLength: 2 softTabs: true @@ -21,9 +21,8 @@ class Project rootDirectory: null editSessions: null ignoredPathRegexes: null - grammarOverridesByPath: null - constructor: (path, @grammarOverridesByPath={}) -> + constructor: (path) -> @setPath(path) @editSessions = [] @buffers = [] @@ -31,23 +30,10 @@ class Project serialize: -> deserializer: 'Project' path: @getPath() - grammarOverridesByPath: @grammarOverridesByPath destroy: -> editSession.destroy() for editSession in @getEditSessions() - addGrammarOverrideForPath: (path, grammar) -> - @grammarOverridesByPath[path] = grammar.scopeName - - removeGrammarOverrideForPath: (path) -> - delete @grammarOverridesByPath[path] - - grammarOverrideForPath: (path) -> - syntax.grammarForScopeName(@grammarOverridesByPath[path]) - - grammarForFilePath: (path, contents) -> - @grammarOverrideForPath(path) or syntax.grammarForFilePath(path, contents) - getPath: -> @rootDirectory?.path @@ -67,9 +53,11 @@ class Project getFilePaths: -> deferred = $.Deferred() - fs.getAllFilePathsAsync @getPath(), (paths) => - paths = paths.filter (path) => not @isPathIgnored(path) - deferred.resolve(paths) + paths = [] + onFile = (path) => paths.push(path) unless @isPathIgnored(path) + onDirectory = -> true + fs.traverseTreeSync(@getPath(), onFile, onDirectory) + deferred.resolve(paths) deferred.promise() isPathIgnored: (path) -> @@ -160,9 +148,7 @@ class Project _.remove(@buffers, buffer) scan: (regex, iterator) -> - command = "#{require.resolve('ag')} --ackmate '#{regex.source}' '#{@getPath()}'" bufferedData = "" - state = 'readingPath' path = null @@ -194,11 +180,22 @@ class Project match = lineText.substr(column, length) iterator({path, range, match}) - ChildProcess.exec command , bufferLines: true, stdout: (data) -> + deferred = $.Deferred() + exit = (code) -> + if code is -1 + deferred.reject({command, code}) + else + deferred.resolve() + stdout = (data) -> lines = data.split('\n') lines.pop() # the last segment is a spurious '' because data always ends in \n due to bufferLines: true for line in lines readPath(line) if state is 'readingPath' readLine(line) if state is 'readingLines' + command = require.resolve('ag') + args = ['--ackmate', regex.source, @getPath()] + new BufferedProcess({command, args, stdout, exit}) + deferred + _.extend Project.prototype, EventEmitter diff --git a/src/app/range.coffee b/src/app/range.coffee index a3870ea66..d72ef6514 100644 --- a/src/app/range.coffee +++ b/src/app/range.coffee @@ -31,7 +31,7 @@ class Range new Range(@start.copy(), @end.copy()) isEqual: (other) -> - if other instanceof Array and other.length == 2 + if _.isArray(other) and other.length == 2 other = new Range(other...) other.start.isEqual(@start) and other.end.isEqual(@end) diff --git a/src/app/repository-status-handler.coffee b/src/app/repository-status-handler.coffee index 5503396ce..7816cf383 100644 --- a/src/app/repository-status-handler.coffee +++ b/src/app/repository-status-handler.coffee @@ -1,5 +1,5 @@ -Git = require 'git' -fs = require 'fs' +Git = require 'git-utils' +fs = require 'fs-utils' module.exports = loadStatuses: (path) -> @@ -7,10 +7,10 @@ module.exports = if repo? workingDirectoryPath = repo.getWorkingDirectory() statuses = {} - for path, status of repo.getRepo().getStatuses() + for path, status of repo.getStatus() statuses[fs.join(workingDirectoryPath, path)] = status - upstream = repo.getAheadBehindCounts() - repo.destroy() + upstream = repo.getAheadBehindCount() + repo.release() else upstream = {} statuses = {} diff --git a/src/app/root-view.coffee b/src/app/root-view.coffee index 9c2eaae40..2c299c92c 100644 --- a/src/app/root-view.coffee +++ b/src/app/root-view.coffee @@ -1,10 +1,10 @@ $ = require 'jquery' {$$} = require 'space-pen' -fs = require 'fs' +fs = require 'fs-utils' _ = require 'underscore' {View} = require 'space-pen' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Editor = require 'editor' Project = require 'project' Pane = require 'pane' @@ -29,8 +29,7 @@ class RootView extends View @div id: 'vertical', outlet: 'vertical', => @subview 'panes', panes ? new PaneContainer - @deserialize: ({ panes, packages, projectPath }) -> - atom.atomPackageStates = packages ? {} + @deserialize: ({ panes }) -> panes = deserialize(panes) if panes?.deserializer is 'PaneContainer' new RootView({panes}) @@ -73,7 +72,6 @@ class RootView extends View version: RootView.version deserializer: 'RootView' panes: @panes.serialize() - packages: atom.serializeAtomPackages() confirmClose: -> @panes.confirmClose() @@ -94,10 +92,6 @@ class RootView extends View afterAttach: (onDom) -> @focus() if onDom - deactivate: -> - atom.deactivateAtomPackages() - @remove() - open: (path, options = {}) -> changeFocus = options.changeFocus ? true path = project.resolve(path) if path? diff --git a/src/app/select-list.coffee b/src/app/select-list.coffee index e2441deff..0b5ff5283 100644 --- a/src/app/select-list.coffee +++ b/src/app/select-list.coffee @@ -20,7 +20,7 @@ class SelectList extends View cancelling: false initialize: -> - requireStylesheet 'select-list.less' + requireStylesheet 'select-list' @miniEditor.getBuffer().on 'changed', => @schedulePopulateList() @miniEditor.on 'focusout', => @cancel() unless @cancelling diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 9377498a2..9be2f7f97 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -271,7 +271,7 @@ class Selection if @isEmpty() start = @cursor.getScreenRow() range = @editSession.bufferRowsForScreenRows(start, start + 1) - if range[1] + if range[1] > range[0] @editSession.buffer.deleteRows(range[0], range[1] - 1) else @editSession.buffer.deleteRow(range[0]) diff --git a/src/app/syntax.coffee b/src/app/syntax.coffee index 9c176fefe..7ab711a14 100644 --- a/src/app/syntax.coffee +++ b/src/app/syntax.coffee @@ -2,40 +2,72 @@ _ = require 'underscore' jQuery = require 'jquery' Specificity = require 'specificity' {$$} = require 'space-pen' -fs = require 'fs' +fs = require 'fs-utils' EventEmitter = require 'event-emitter' +NullGrammar = require 'null-grammar' +nodePath = require 'path' +pathSplitRegex = new RegExp("[#{nodePath.sep}.]") module.exports = class Syntax + registerDeserializer(this) + + @deserialize: ({grammarOverridesByPath}) -> + syntax = new Syntax() + syntax.grammarOverridesByPath = grammarOverridesByPath + syntax + constructor: -> @grammars = [] @grammarsByFileType = {} @grammarsByScopeName = {} - @globalProperties = {} + @grammarOverridesByPath = {} @scopedPropertiesIndex = 0 @scopedProperties = [] + @nullGrammar = new NullGrammar + + serialize: -> + { deserializer: @constructor.name, @grammarOverridesByPath } addGrammar: (grammar) -> @grammars.push(grammar) - for fileType in grammar.fileTypes - @grammarsByFileType[fileType] = grammar - @grammarsByScopeName[grammar.scopeName] = grammar + @grammarsByFileType[fileType] = grammar for fileType in grammar.fileTypes + @grammarsByScopeName[grammar.scopeName] = grammar - grammarForFilePath: (filePath, fileContents) -> - return @grammarsByFileType["txt"] unless filePath + removeGrammar: (grammar) -> + if _.include(@grammars, grammar) + _.remove(@grammars, grammar) + delete @grammarsByFileType[fileType] for fileType in grammar.fileTypes + delete @grammarsByScopeName[grammar.scopeName] - extension = fs.extension(filePath)?[1..] - if filePath and extension.length == 0 - extension = fs.base(filePath) + setGrammarOverrideForPath: (path, scopeName) -> + @grammarOverridesByPath[path] = scopeName - @grammarByFirstLineRegex(filePath, fileContents) or - @grammarsByFileType[extension] or - @grammarByFileTypeSuffix(filePath) or - @grammarsByFileType["txt"] + clearGrammarOverrideForPath: (path) -> + delete @grammarOverridesByPath[path] - grammarByFileTypeSuffix: (filePath) -> + clearGrammarOverrides: -> + @grammarOverridesByPath = {} + + selectGrammar: (filePath, fileContents) -> + + return @grammarsByFileType["txt"] ? @nullGrammar unless filePath + + @grammarOverrideForPath(filePath) ? + @grammarByFirstLineRegex(filePath, fileContents) ? + @grammarByPath(filePath) ? + @grammarsByFileType["txt"] ? + @nullGrammar + + grammarOverrideForPath: (path) -> + @grammarsByScopeName[@grammarOverridesByPath[path]] + + grammarByPath: (path) -> + pathComponents = path.split(pathSplitRegex) for fileType, grammar of @grammarsByFileType - return grammar if _.endsWith(filePath, fileType) + fileTypeComponents = fileType.split(pathSplitRegex) + pathSuffix = pathComponents[-fileTypeComponents.length..-1] + return grammar if _.isEqual(pathSuffix, fileTypeComponents) grammarByFirstLineRegex: (filePath, fileContents) -> try @@ -68,18 +100,24 @@ class Syntax @grammarsByScopeName[scopeName] addProperties: (args...) -> - selector = args.shift() if args.length > 1 - properties = args.shift() + name = args.shift() if args.length > 2 + [selector, properties] = args - if selector - @scopedProperties.unshift( - selector: selector, - properties: properties, - specificity: Specificity(selector), - index: @scopedPropertiesIndex++ - ) - else - _.extend(@globalProperties, properties) + @scopedProperties.unshift( + name: name + selector: selector, + properties: properties, + specificity: Specificity(selector), + index: @scopedPropertiesIndex++ + ) + + removeProperties: (name) -> + for properties in @scopedProperties.filter((properties) -> properties.name is name) + _.remove(@scopedProperties, properties) + + clearProperties: -> + @scopedProperties = [] + @scopedPropertiesIndex = 0 getProperty: (scope, keyPath) -> for object in @propertiesForScope(scope, keyPath) @@ -95,7 +133,7 @@ class Syntax while element matchingProperties.push(@matchingPropertiesForElement(element, candidates)...) element = element.parentNode - matchingProperties.concat([@globalProperties]) + matchingProperties matchingPropertiesForElement: (element, candidates) -> matchingScopedProperties = candidates.filter ({selector}) -> @@ -125,4 +163,13 @@ class Syntax else element[0] + cssSelectorFromScopeSelector: (scopeSelector) -> + scopeSelector.split(', ').map((commaFragment) -> + commaFragment.split(' ').map((spaceFragment) -> + spaceFragment.split('.').map((dotFragment) -> + '.' + dotFragment.replace(/\+/g, '\\+') + ).join('') + ).join(' ') + ).join(', ') + _.extend(Syntax.prototype, EventEmitter) diff --git a/src/app/buffer.coffee b/src/app/text-buffer.coffee similarity index 99% rename from src/app/buffer.coffee rename to src/app/text-buffer.coffee index 00d0483e4..2c5c623e3 100644 --- a/src/app/buffer.coffee +++ b/src/app/text-buffer.coffee @@ -1,5 +1,5 @@ _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' File = require 'file' Point = require 'point' Range = require 'range' diff --git a/src/app/text-mate-grammar.coffee b/src/app/text-mate-grammar.coffee index 01acb2f77..93fe9559f 100644 --- a/src/app/text-mate-grammar.coffee +++ b/src/app/text-mate-grammar.coffee @@ -1,22 +1,24 @@ _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' plist = require 'plist' Token = require 'token' -OnigRegExp = require 'onig-reg-exp' -OnigScanner = require 'onig-scanner' +CSON = require 'cson' +{OnigRegExp, OnigScanner} = require 'oniguruma' module.exports = class TextMateGrammar @readFromPath: (path) -> - grammarContent = null - if fs.isObjectPath(path) - grammarContent = fs.readObject(path) - else - plist.parseString fs.read(path), (e, data) -> - throw new Error(e) if e - grammarContent = data[0] - throw new Error("Failed to load grammar at path `#{path}`") unless grammarContent - grammarContent + fs.readPlist(path) + + @load: (path, done) -> + fs.readObjectAsync path, (err, object) -> + if err + done(err) + else + done(null, new TextMateGrammar(object)) + + @loadSync: (path) -> + new TextMateGrammar(fs.readObject(path)) name: null fileTypes: null @@ -28,7 +30,7 @@ class TextMateGrammar constructor: ({ @name, @fileTypes, @scopeName, patterns, repository, @foldingStopMarker, firstLineMatch}) -> @initialRule = new Rule(this, {@scopeName, patterns}) @repository = {} - @firstLineRegex = OnigRegExp.create(firstLineMatch) if firstLineMatch + @firstLineRegex = new OnigRegExp(firstLineMatch) if firstLineMatch @fileTypes ?= [] for name, data of repository @@ -39,9 +41,10 @@ class TextMateGrammar ruleStack = new Array(ruleStack...) # clone ruleStack tokens = [] position = 0 - loop scopes = scopesFromStack(ruleStack) + previousRuleStackLength = ruleStack.length + previousPosition = position if line.length == 0 tokens = [new Token(value: "", scopes: scopes)] @@ -69,6 +72,10 @@ class TextMateGrammar )) break + if position == previousPosition and ruleStack.length == previousRuleStackLength + console.error("Popping rule because it loops at column #{position} of line '#{line}'", _.clone(ruleStack)) + ruleStack.pop() + ruleStack.forEach (rule) -> rule.clearAnchorPosition() { tokens, ruleStack } @@ -111,7 +118,7 @@ class Rule regex = pattern.regexSource regexes.push regex if regex - regexScanner = OnigScanner.create(regexes) + regexScanner = new OnigScanner(regexes) regexScanner.patterns = patterns @scannersByBaseGrammarName[baseGrammar.name] = regexScanner unless anchored regexScanner @@ -152,10 +159,10 @@ class Pattern backReferences: null anchored: false - constructor: (@grammar, { name, contentName, @include, match, begin, end, captures, beginCaptures, endCaptures, patterns, @popRule, hasBackReferences}) -> + constructor: (@grammar, { name, contentName, @include, match, begin, end, captures, beginCaptures, endCaptures, patterns, @popRule, @hasBackReferences}) -> @scopeName = name ? contentName # TODO: We need special treatment of contentName if match - if @hasBackReferences = hasBackReferences ? /\\\d+/.test(match) + if (end or @popRule) and @hasBackReferences ?= /\\\d+/.test(match) @match = match else @regexSource = match diff --git a/src/app/text-mate-package.coffee b/src/app/text-mate-package.coffee index 2929e1883..a6ef9b8fd 100644 --- a/src/app/text-mate-package.coffee +++ b/src/app/text-mate-package.coffee @@ -1,101 +1,89 @@ Package = require 'package' -fs = require 'fs' +fsUtils = require 'fs-utils' plist = require 'plist' _ = require 'underscore' TextMateGrammar = require 'text-mate-grammar' +async = require 'async' module.exports = class TextMatePackage extends Package @testName: (packageName) -> /(\.|_|-)tmbundle$/.test(packageName) - @cssSelectorFromScopeSelector: (scopeSelector) -> - scopeSelector.split(', ').map((commaFragment) -> - commaFragment.split(' ').map((spaceFragment) -> - spaceFragment.split('.').map((dotFragment) -> - '.' + dotFragment.replace(/\+/g, '\\+') - ).join('') - ).join(' ') - ).join(', ') + @getLoadQueue: -> + return @loadQueue if @loadQueue + @loadQueue = async.queue (pack, done) -> pack.loadGrammars(done) + @loadQueue.drain = -> syntax.trigger 'grammars-loaded' + @loadQueue constructor: -> super - @preferencesPath = fs.join(@path, "Preferences") - @syntaxesPath = fs.join(@path, "Syntaxes") + @preferencesPath = fsUtils.join(@path, "Preferences") + @syntaxesPath = fsUtils.join(@path, "Syntaxes") @grammars = [] - load: -> - try - @loadGrammars() - catch e - console.warn "Failed to load package at '#{@path}'", e.stack - this + load: ({sync}={}) -> + if sync + @loadGrammarsSync() + else + TextMatePackage.getLoadQueue().push(this) + @loadScopedProperties() - activate: -> # no-op + activate: -> + syntax.addGrammar(grammar) for grammar in @grammars + for { selector, properties } in @scopedProperties + syntax.addProperties(@path, selector, properties) + + deactivate: -> + syntax.removeGrammar(grammar) for grammar in @grammars + syntax.removeProperties(@path) + + legalGrammarExtensions: ['plist', 'tmLanguage', 'tmlanguage'] + + loadGrammars: (done) -> + fsUtils.isDirectoryAsync @syntaxesPath, (isDirectory) => + if isDirectory + fsUtils.listAsync @syntaxesPath, @legalGrammarExtensions, (err, paths) => + return console.log("Error loading grammars of TextMate package '#{@path}':", err.stack, err) if err + async.eachSeries paths, @loadGrammarAtPath, done + + loadGrammarAtPath: (path, done) => + TextMateGrammar.load path, (err, grammar) => + return console.log("Error loading grammar at path '#{path}':", err.stack ? err) if err + @addGrammar(grammar) + done() + + loadGrammarsSync: -> + for path in fsUtils.list(@syntaxesPath, @legalGrammarExtensions) ? [] + @addGrammar(TextMateGrammar.loadSync(path)) + + addGrammar: (grammar) -> + @grammars.push(grammar) + syntax.addGrammar(grammar) if atom.isPackageActive(@path) getGrammars: -> @grammars - readGrammars: -> - grammars = [] - for grammarPath in fs.list(@syntaxesPath) - try - grammars.push(TextMateGrammar.readFromPath(grammarPath)) - catch e - console.warn "Failed to load grammar at path '#{grammarPath}'", e.stack - grammars - - addGrammar: (rawGrammar) -> - grammar = new TextMateGrammar(rawGrammar) - @grammars.push(grammar) - syntax.addGrammar(grammar) - - loadGrammars: (rawGrammars) -> - rawGrammars = @readGrammars() unless rawGrammars? - - @grammars = [] - @addGrammar(rawGrammar) for rawGrammar in rawGrammars - @loadScopedProperties() - loadScopedProperties: -> - for { selector, properties } in @getScopedProperties() - syntax.addProperties(selector, properties) - - getScopedProperties: -> - scopedProperties = [] + @scopedProperties = [] for grammar in @getGrammars() if properties = @propertiesFromTextMateSettings(grammar) - selector = @cssSelectorFromScopeSelector(grammar.scopeName) - scopedProperties.push({selector, properties}) + selector = syntax.cssSelectorFromScopeSelector(grammar.scopeName) + @scopedProperties.push({selector, properties}) for {scope, settings} in @getTextMatePreferenceObjects() if properties = @propertiesFromTextMateSettings(settings) - selector = @cssSelectorFromScopeSelector(scope) if scope? - scopedProperties.push({selector, properties}) - - scopedProperties - - readObjectFromPath: (path, callback) -> - object = null - error = null - if fs.isObjectPath(path) - object = fs.readObject(path) - else - plist.parseString fs.read(path), (e, data) -> - error = e - object = data[0] - error = throw new Error("Failed to load object at path `#{path}`") unless object - callback(error, object) + selector = syntax.cssSelectorFromScopeSelector(scope) if scope? + @scopedProperties.push({selector, properties}) getTextMatePreferenceObjects: -> preferenceObjects = [] - if fs.exists(@preferencesPath) - for preferencePath in fs.list(@preferencesPath) - @readObjectFromPath preferencePath, (e, object) => - if e - console.warn "Failed to parse preference at path '#{preferencePath}'", e.stack - else - preferenceObjects.push(object) + if fsUtils.exists(@preferencesPath) + for preferencePath in fsUtils.list(@preferencesPath) + try + preferenceObjects.push(fsUtils.readObject(preferencePath)) + catch e + console.warn "Failed to parse preference at path '#{preferencePath}'", e.stack preferenceObjects propertiesFromTextMateSettings: (textMateSettings) -> @@ -113,6 +101,3 @@ class TextMatePackage extends Package foldEndPattern: textMateSettings.foldingStopMarker ) { editor: editorProperties } if _.size(editorProperties) > 0 - - cssSelectorFromScopeSelector: (scopeSelector) -> - @constructor.cssSelectorFromScopeSelector(scopeSelector) diff --git a/src/app/text-mate-theme.coffee b/src/app/text-mate-theme.coffee index f2c1d1f92..2424bc2d3 100644 --- a/src/app/text-mate-theme.coffee +++ b/src/app/text-mate-theme.coffee @@ -1,5 +1,5 @@ _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' plist = require 'plist' Theme = require 'theme' @@ -18,10 +18,9 @@ class TextMateTheme extends Theme super buildRulesets: -> - plist.parseString fs.read(@path), (error, [{settings}]) => - throw new Error("Error loading theme at '#{@path}': #{error}") if error - @buildGlobalSettingsRulesets(settings[0]) - @buildScopeSelectorRulesets(settings[1..]) + {settings} = plist.parseFileSync(@path) + @buildGlobalSettingsRulesets(settings[0]) + @buildScopeSelectorRulesets(settings[1..]) getStylesheet: -> lines = [] diff --git a/src/app/theme.coffee b/src/app/theme.coffee index ba35e23e1..6ca385d66 100644 --- a/src/app/theme.coffee +++ b/src/app/theme.coffee @@ -1,4 +1,4 @@ -fs = require 'fs' +fs = require 'fs-utils' module.exports = class Theme diff --git a/src/app/window.coffee b/src/app/window.coffee index bba97a751..f6c513c2d 100644 --- a/src/app/window.coffee +++ b/src/app/window.coffee @@ -1,7 +1,7 @@ -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' -ChildProcess = require 'child-process' {less} = require 'less' +{spawn} = require 'child_process' require 'jquery-extensions' require 'underscore-extensions' require 'space-pen-extensions' @@ -17,27 +17,21 @@ window.setUpEnvironment = -> Keymap = require 'keymap' window.rootViewParentSelector = 'body' - window.platform = $native.getPlatform() window.config = new Config - window.syntax = new Syntax + window.syntax = deserialize(atom.getWindowState('syntax')) ? new Syntax window.pasteboard = new Pasteboard window.keymap = new Keymap() $(document).on 'keydown', keymap.handleKeyEvent keymap.bindDefaultKeys() - requireStylesheet 'reset.less' - requireStylesheet 'atom.less' - requireStylesheet 'tabs.less' - requireStylesheet 'tree-view.less' - requireStylesheet 'status-bar.less' - requireStylesheet 'command-panel.less' - requireStylesheet 'fuzzy-finder.less' - requireStylesheet 'overlay.less' - requireStylesheet 'popover-list.less' - requireStylesheet 'notification.less' - requireStylesheet 'markdown.less' + requireStylesheet 'reset' + requireStylesheet 'atom' + requireStylesheet 'overlay' + requireStylesheet 'popover-list' + requireStylesheet 'notification' + requireStylesheet 'markdown' - if nativeStylesheetPath = require.resolve("#{platform}.css") + if nativeStylesheetPath = fs.resolveOnLoadPath(process.platform, ['css', 'less']) requireStylesheet(nativeStylesheetPath) # This method is only called when opening a real application window @@ -53,11 +47,10 @@ window.startup = -> handleWindowEvents() config.load() - atom.loadTextPackage() keymap.loadBundledKeymaps() atom.loadThemes() atom.loadPackages() - buildProjectAndRootView() + deserializeWindowState() atom.activatePackages() keymap.loadUserKeymaps() atom.requireUserInitScript() @@ -67,10 +60,13 @@ window.startup = -> window.shutdown = -> return if not project and not rootView atom.setWindowState('pathToOpen', project.getPath()) - atom.setRootViewStateForPath project.getPath(), - project: project.serialize() - rootView: rootView.serialize() - rootView.deactivate() + atom.setWindowState('project', project.serialize()) + atom.setWindowState('syntax', syntax.serialize()) + atom.setWindowState('rootView', rootView.serialize()) + atom.deactivatePackages() + atom.setWindowState('packageStates', atom.packageStates) + rootView.remove() + atom.saveWindowState() project.destroy() git?.destroy() $(window).off('focus blur before') @@ -84,7 +80,7 @@ window.installAtomCommand = (commandPath) -> bundledCommandPath = fs.resolve(window.resourcePath, 'atom.sh') if bundledCommandPath? fs.write(commandPath, fs.read(bundledCommandPath)) - ChildProcess.exec("chmod u+x '#{commandPath}'") + spawn('chmod', ['u+x', commandPath]) window.handleWindowEvents = -> $(window).command 'window:toggle-full-screen', => atom.toggleFullScreen() @@ -92,13 +88,16 @@ window.handleWindowEvents = -> $(window).on 'blur', -> $("body").addClass('is-blurred') $(window).command 'window:close', => confirmClose() -window.buildProjectAndRootView = -> +window.deserializeWindowState = -> RootView = require 'root-view' Project = require 'project' Git = require 'git' pathToOpen = atom.getPathToOpen() - windowState = atom.getRootViewStateForPath(pathToOpen) ? {} + + windowState = atom.getWindowState() + + atom.packageStates = windowState.packageStates ? {} window.project = deserialize(windowState.project) ? new Project(pathToOpen) window.rootView = deserialize(windowState.rootView) ? new RootView @@ -115,25 +114,30 @@ window.buildProjectAndRootView = -> window.stylesheetElementForId = (id) -> $("head style[id='#{id}']") +window.resolveStylesheet = (path) -> + if fs.extension(path).length > 0 + fs.resolveOnLoadPath(path) + else + fs.resolveOnLoadPath(path, ['css', 'less']) + window.requireStylesheet = (path) -> - if fullPath = require.resolve(path) + if fullPath = window.resolveStylesheet(path) content = window.loadStylesheet(fullPath) window.applyStylesheet(fullPath, content) else - console.log "bad", path throw new Error("Could not find a file at path '#{path}'") window.loadStylesheet = (path) -> content = fs.read(path) if fs.extension(path) == '.less' (new less.Parser).parse content, (e, tree) -> - throw new Error(e.message, file, e.line) if e + throw new Error(e.message, path, e.line) if e content = tree.toCSS() content window.removeStylesheet = (path) -> - unless fullPath = require.resolve(path) + unless fullPath = window.resolveStylesheet(path) throw new Error("Could not find a file at path '#{path}'") window.stylesheetElementForId(fullPath).remove() @@ -189,6 +193,12 @@ window.measure = (description, fn) -> console.log description, result value +window.profile = (description, fn) -> + measure description, -> + console.profile(description) + value = fn() + console.profileEnd(description) + value confirmClose = -> - rootView.confirmClose().done -> window.close() \ No newline at end of file + rootView.confirmClose().done -> window.close() diff --git a/src/packages/autocomplete/spec/autocomplete-spec.coffee b/src/packages/autocomplete/spec/autocomplete-spec.coffee index 9bfa9af7f..b525a8fe7 100644 --- a/src/packages/autocomplete/spec/autocomplete-spec.coffee +++ b/src/packages/autocomplete/spec/autocomplete-spec.coffee @@ -1,7 +1,7 @@ $ = require 'jquery' AutocompleteView = require 'autocomplete/lib/autocomplete-view' Autocomplete = require 'autocomplete/lib/autocomplete' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Editor = require 'editor' RootView = require 'root-view' @@ -14,7 +14,7 @@ describe "Autocomplete", -> describe "@activate()", -> it "activates autocomplete on all existing and future editors (but not on autocomplete's own mini editor)", -> spyOn(AutocompleteView.prototype, 'initialize').andCallThrough() - autocompletePackage = window.loadPackage("autocomplete") + autocompletePackage = atom.activatePackage("autocomplete") expect(AutocompleteView.prototype.initialize).not.toHaveBeenCalled() leftEditor = rootView.getActiveView() @@ -41,7 +41,7 @@ describe "AutocompleteView", -> beforeEach -> window.rootView = new RootView editor = new Editor(editSession: project.buildEditSession('sample.js')) - window.loadPackage('autocomplete') + atom.activatePackage('autocomplete') autocomplete = new AutocompleteView(editor) miniEditor = autocomplete.miniEditor diff --git a/src/packages/autoflow/spec/autoflow-spec.coffee b/src/packages/autoflow/spec/autoflow-spec.coffee index 190ac238c..c497f6292 100644 --- a/src/packages/autoflow/spec/autoflow-spec.coffee +++ b/src/packages/autoflow/spec/autoflow-spec.coffee @@ -6,7 +6,7 @@ describe "Autoflow package", -> beforeEach -> window.rootView = new RootView rootView.open() - window.loadPackage 'autoflow' + atom.activatePackage('autoflow') editor = rootView.getActiveView() config.set('editor.preferredLineLength', 30) diff --git a/src/packages/bracket-matcher/lib/bracket-matcher.coffee b/src/packages/bracket-matcher/lib/bracket-matcher.coffee index 52ad5aa50..11398aad2 100644 --- a/src/packages/bracket-matcher/lib/bracket-matcher.coffee +++ b/src/packages/bracket-matcher/lib/bracket-matcher.coffee @@ -41,7 +41,7 @@ module.exports = goToMatchingPair: (editor) -> return unless @pairHighlighted - return unless underlayer = editor.pane()?.find('.underlayer') + return unless underlayer = editor.getPane()?.find('.underlayer') position = editor.getCursorBufferPosition() previousPosition = position.translate([0, -1]) @@ -127,7 +127,7 @@ module.exports = startPairPosition updateMatch: (editor) -> - return unless underlayer = editor.pane()?.find('.underlayer') + return unless underlayer = editor.getPane()?.find('.underlayer') @hideHighlightViews(editor) if @pairHighlighted @pairHighlighted = false diff --git a/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee b/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee index 099be0926..9a44ba3a7 100644 --- a/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee +++ b/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee @@ -6,7 +6,7 @@ describe "bracket matching", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - window.loadPackage('bracket-matcher') + atom.activatePackage('bracket-matcher') rootView.attachToDom() editor = rootView.getActiveView() editSession = editor.activeEditSession diff --git a/src/packages/command-logger/lib/command-logger-view.coffee b/src/packages/command-logger/lib/command-logger-view.coffee index 584c01d5a..e4dd5838d 100644 --- a/src/packages/command-logger/lib/command-logger-view.coffee +++ b/src/packages/command-logger/lib/command-logger-view.coffee @@ -96,7 +96,7 @@ class CommandLoggerView extends ScrollView w = @treeMap.width() h = @treeMap.height() - d3 = require 'd3.v3' + d3 = require 'd3' x = d3.scale.linear().range([0, w]) y = d3.scale.linear().range([0, h]) diff --git a/src/packages/command-logger/lib/command-logger.coffee b/src/packages/command-logger/lib/command-logger.coffee index 442fd1710..d5a0dc573 100644 --- a/src/packages/command-logger/lib/command-logger.coffee +++ b/src/packages/command-logger/lib/command-logger.coffee @@ -21,8 +21,8 @@ module.exports = eventNameLog.lastRun = new Date().getTime() trigger = $.fn.trigger @originalTrigger = trigger - $.fn.trigger = (eventName) -> - eventName = eventName.type if eventName.type + $.fn.trigger = (event) -> + eventName = event.type ? event registerTriggeredEvent(eventName) if $(this).events()[eventName] trigger.apply(this, arguments) diff --git a/src/packages/command-logger/spec/command-logger-spec.coffee b/src/packages/command-logger/spec/command-logger-spec.coffee index 8feec78bd..96365b469 100644 --- a/src/packages/command-logger/spec/command-logger-spec.coffee +++ b/src/packages/command-logger/spec/command-logger-spec.coffee @@ -7,7 +7,7 @@ describe "CommandLogger", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - commandLogger = window.loadPackage('command-logger').mainModule + commandLogger = atom.activatePackage('command-logger').mainModule commandLogger.eventLog = {} editor = rootView.getActiveView() diff --git a/src/packages/command-palette/lib/command-palette-view.coffee b/src/packages/command-palette/lib/command-palette-view.coffee index 2acb80753..34988e751 100644 --- a/src/packages/command-palette/lib/command-palette-view.coffee +++ b/src/packages/command-palette/lib/command-palette-view.coffee @@ -13,7 +13,6 @@ class CommandPaletteView extends SelectList filterKey: 'eventDescription' - previouslyFocusedElement: null keyBindings: null initialize: -> @@ -30,10 +29,14 @@ class CommandPaletteView extends SelectList attach: -> super - @keyBindings = _.losslessInvert(keymap.bindingsForElement(@previouslyFocusedElement)) + if @previouslyFocusedElement[0] + @eventElement = @previouslyFocusedElement + else + @eventElement = rootView + @keyBindings = _.losslessInvert(keymap.bindingsForElement(@eventElement)) events = [] - for eventName, eventDescription of _.extend($(window).events(), @previouslyFocusedElement.events()) + for eventName, eventDescription of _.extend($(window).events(), @eventElement.events()) events.push({eventName, eventDescription}) if eventDescription events = _.sortBy events, (e) -> e.eventDescription @@ -53,4 +56,4 @@ class CommandPaletteView extends SelectList confirmed: ({eventName}) -> @cancel() - @previouslyFocusedElement.trigger(eventName) + @eventElement.trigger(eventName) diff --git a/src/packages/command-palette/spec/command-palette-spec.coffee b/src/packages/command-palette/spec/command-palette-spec.coffee index 414c53996..a0de19c61 100644 --- a/src/packages/command-palette/spec/command-palette-spec.coffee +++ b/src/packages/command-palette/spec/command-palette-spec.coffee @@ -9,7 +9,7 @@ describe "CommandPalette", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - window.loadPackage("command-palette") + atom.activatePackage("command-palette") rootView.attachToDom().focus() rootView.trigger 'command-palette:toggle' palette = rootView.find('.command-palette').view() @@ -81,3 +81,20 @@ describe "CommandPalette", -> expect(activeEditor.isFocused).toBeTruthy() expect(eventHandler).toHaveBeenCalled() expect(palette.hasParent()).toBeFalsy() + + describe "when no element has focus", -> + it "uses the root view as the element to display and trigger events for", -> + rootView.trigger 'command-palette:toggle' + $(':focus').blur() + rootView.trigger 'command-palette:toggle' + keyBindings = _.losslessInvert(keymap.bindingsForElement(rootView.getActiveView())) + for eventName, description of rootView.events() + eventLi = palette.list.children("[data-event-name='#{eventName}']") + if description + expect(eventLi).toExist() + expect(eventLi.find('.label')).toHaveText(description) + expect(eventLi.find('.label').attr('title')).toBe(eventName) + for binding in keyBindings[eventName] ? [] + expect(eventLi.find(".key-binding:contains(#{binding})")).toExist() + else + expect(eventLi).not.toExist() diff --git a/src/packages/command-panel/lib/command-interpreter.coffee b/src/packages/command-panel/lib/command-interpreter.coffee index c2328ceed..07f53672e 100644 --- a/src/packages/command-panel/lib/command-interpreter.coffee +++ b/src/packages/command-panel/lib/command-interpreter.coffee @@ -1,4 +1,4 @@ -fs = require 'fs' +fs = require 'fs-utils' PEG = require 'pegjs' module.exports = @@ -11,8 +11,12 @@ class CommandInterpreter @lastRelativeAddress = compositeCommand if compositeCommand.isRelativeAddress() compositeCommand.execute(@project, activeEditSession) - repeatRelativeAddress: (activeEditSession) -> - @lastRelativeAddress?.execute(@project, activeEditSession) + repeatRelativeAddress: (activeEditSession, {reverse}={}) -> + return unless @lastRelativeAddress + reverse ?= false + previousSelectionRange = activeEditSession.getSelection().getBufferRange() + address = if reverse then @lastRelativeAddress.reverse() else @lastRelativeAddress - repeatRelativeAddressInReverse: (activeEditSession) -> - @lastRelativeAddress?.reverse().execute(@project, activeEditSession) + address.execute(@project, activeEditSession).done -> + currentSelectionRange = activeEditSession.getSelection().getBufferRange() + $native.beep() if previousSelectionRange.isEqual(currentSelectionRange) diff --git a/src/packages/command-panel/lib/command-panel-view.coffee b/src/packages/command-panel/lib/command-panel-view.coffee index 2430c7ae0..a0255a6c0 100644 --- a/src/packages/command-panel/lib/command-panel-view.coffee +++ b/src/packages/command-panel/lib/command-panel-view.coffee @@ -44,7 +44,7 @@ class CommandPanelView extends View rootView.command 'command-panel:find-in-file', => @attach('/') rootView.command 'command-panel:find-in-project', => @attach('Xx/') rootView.command 'command-panel:repeat-relative-address', => @repeatRelativeAddress() - rootView.command 'command-panel:repeat-relative-address-in-reverse', => @repeatRelativeAddressInReverse() + rootView.command 'command-panel:repeat-relative-address-in-reverse', => @repeatRelativeAddress(reverse: true) rootView.command 'command-panel:set-selection-as-regex-address', => @setSelectionAsLastRelativeAddress() @on 'click', '.expand', @onExpandAll @@ -65,6 +65,9 @@ class CommandPanelView extends View destroy: -> @previewList.destroy() + rootView.off "command-panel:toggle-preview command-panel:find-in-file command-panel:find-in-project \ + command-panel:repeat-relative-address command-panel:repeat-relative-address-in-reverse command-panel:set-selection-as-regex-address" + @remove() toggle: -> if @miniEditor.isFocused @@ -115,7 +118,7 @@ class CommandPanelView extends View escapedCommand: -> @miniEditor.getText() - execute: (command=@escapedCommand())-> + execute: (command=@escapedCommand()) -> @loadingMessage.show() @errorMessages.empty() @@ -138,6 +141,7 @@ class CommandPanelView extends View else @detach() catch error + @loadingMessage.hide() if error.name is "SyntaxError" @flashError() return @@ -154,11 +158,8 @@ class CommandPanelView extends View @historyIndex++ @miniEditor.setText(@history[@historyIndex] or '') - repeatRelativeAddress: -> - @commandInterpreter.repeatRelativeAddress(rootView.getActivePaneItem()) - - repeatRelativeAddressInReverse: -> - @commandInterpreter.repeatRelativeAddressInReverse(rootView.getActivePaneItem()) + repeatRelativeAddress: (options) -> + @commandInterpreter.repeatRelativeAddress(rootView.getActivePaneItem(), options) setSelectionAsLastRelativeAddress: -> selection = rootView.getActiveView().getSelectedText() diff --git a/src/packages/command-panel/lib/commands/address.coffee b/src/packages/command-panel/lib/commands/address.coffee index 7d0f88214..ffa89f8ff 100644 --- a/src/packages/command-panel/lib/commands/address.coffee +++ b/src/packages/command-panel/lib/commands/address.coffee @@ -6,7 +6,7 @@ module.exports = class Address extends Command compile: (project, buffer, ranges) -> deferred = $.Deferred() - deferred.resolve ranges.map (range) => + operations = ranges.map (range) => newRange = @getRange(buffer, range) new Operation @@ -15,6 +15,7 @@ class Address extends Command bufferRange: newRange errorMessage: @errorMessage + deferred.resolve(operations) deferred.promise() isAddress: -> true diff --git a/src/packages/command-panel/lib/commands/select-all-matches-in-project.coffee b/src/packages/command-panel/lib/commands/select-all-matches-in-project.coffee index 25acc5fbb..619378ed3 100644 --- a/src/packages/command-panel/lib/commands/select-all-matches-in-project.coffee +++ b/src/packages/command-panel/lib/commands/select-all-matches-in-project.coffee @@ -16,7 +16,7 @@ class SelectAllMatchesInProject extends Command promise = project.scan @regex, ({path, range}) -> operations.push(new Operation( project: project - buffer: project.bufferForPath(path) + path: path bufferRange: range )) diff --git a/src/packages/command-panel/lib/operation-view.coffee b/src/packages/command-panel/lib/operation-view.coffee index 297ef93b6..666aa8836 100644 --- a/src/packages/command-panel/lib/operation-view.coffee +++ b/src/packages/command-panel/lib/operation-view.coffee @@ -4,7 +4,7 @@ module.exports = class OperationView extends View @content: ({operation} = {}) -> {prefix, suffix, match, range} = operation.preview() - @li 'data-index': operation.index, class: 'operation', => + @li class: 'operation', => @span range.start.row + 1, class: 'line-number' @span class: 'preview', => @span prefix diff --git a/src/packages/command-panel/lib/operation.coffee b/src/packages/command-panel/lib/operation.coffee index 52e45d544..9be9ad7f6 100644 --- a/src/packages/command-panel/lib/operation.coffee +++ b/src/packages/command-panel/lib/operation.coffee @@ -1,22 +1,30 @@ module.exports = class Operation - constructor: ({@project, @buffer, bufferRange, @newText, @preserveSelection, @errorMessage}) -> - @buffer.retain() - @marker = @buffer.markRange(bufferRange) + constructor: ({@project, @path, @buffer, @bufferRange, @newText, @preserveSelection, @errorMessage}) -> + if @buffer? + @buffer.retain() + @getMarker() + + getMarker: -> + @marker ?= @getBuffer().markRange(@bufferRange) + + getBuffer: -> + @buffer ?= @project.bufferForPath(@path).retain() getPath: -> - @project.relativize(@buffer.getPath()) + path = @path ? @getBuffer().getPath() + @project.relativize(path) getBufferRange: -> - @buffer.getMarkerRange(@marker) + @getBuffer().getMarkerRange(@getMarker()) execute: (editSession) -> - @buffer.change(@getBufferRange(), @newText) if @newText + @getBuffer().change(@getBufferRange(), @newText) if @newText @getBufferRange() unless @preserveSelection preview: -> - range = @buffer.getMarkerRange(@marker) - line = @buffer.lineForRow(range.start.row) + range = @getBuffer().getMarkerRange(@getMarker()) + line = @getBuffer().lineForRow(range.start.row) prefix = line[0...range.start.column] match = line[range.start.column...range.end.column] suffix = line[range.end.column..] @@ -24,5 +32,5 @@ class Operation {prefix, suffix, match, range} destroy: -> - @buffer.destroyMarker(@marker) - @buffer.release() + @buffer?.destroyMarker(@marker) if @marker? + @buffer?.release() diff --git a/src/packages/command-panel/lib/path-view.coffee b/src/packages/command-panel/lib/path-view.coffee index dbd93751d..9561d019b 100644 --- a/src/packages/command-panel/lib/path-view.coffee +++ b/src/packages/command-panel/lib/path-view.coffee @@ -1,20 +1,18 @@ {View} = require 'space-pen' -fs = require 'fs' +fs = require 'fs-utils' OperationView = require './operation-view' $ = require 'jquery' module.exports = class PathView extends View - @content: ({path, operations, previewList} = {}) -> + @content: ({path, previewList} = {}) -> classes = ['path'] classes.push('readme') if fs.isReadmePath(path) @li class: classes.join(' '), => @div outlet: 'pathDetails', class: 'path-details', => @span class: 'path-name', path - @span "(#{operations.length})", class: 'path-match-number' + @span outlet: 'description', class: 'path-match-number' @ul outlet: 'matches', class: 'matches', => - for operation in operations - @subview "operation#{operation.index}", new OperationView({operation, previewList}) initialize: ({@previewList}) -> @pathDetails.on 'mousedown', => @toggle(true) @@ -27,6 +25,10 @@ class PathView extends View @toggle(true) false + addOperation: (operation) -> + @matches.append new OperationView({operation, @previewList}) + @description.text("(#{@matches.find('li').length})") + isSelected: -> @hasClass('selected') or @find('.selected').length diff --git a/src/packages/command-panel/lib/preview-list.coffee b/src/packages/command-panel/lib/preview-list.coffee index 5430d7ae9..7f70db89d 100644 --- a/src/packages/command-panel/lib/preview-list.coffee +++ b/src/packages/command-panel/lib/preview-list.coffee @@ -1,7 +1,7 @@ $ = require 'jquery' ScrollView = require 'scroll-view' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' PathView = require './path-view' OperationView = require './operation-view' @@ -11,12 +11,17 @@ class PreviewList extends ScrollView @ol class: 'preview-list', tabindex: -1 operations: null + viewsForPath: null + pixelOverdraw: 100 + lastRenderedOperationIndex: null initialize: -> super @on 'core:move-down', => @selectNextOperation(); false @on 'core:move-up', => @selectPreviousOperation(); false + @on 'scroll', => + @renderOperations() if @scrollBottom() >= (@prop('scrollHeight')) @command 'command-panel:collapse-all', => @collapseAllPaths() @command 'command-panel:expand-all', => @expandAllPaths() @@ -25,6 +30,7 @@ class PreviewList extends ScrollView @children().each (index, element) -> $(element).view().expand() collapseAllPaths: -> + @renderOperations(renderAll: true) @children().each (index, element) -> $(element).view().collapse() destroy: -> @@ -35,23 +41,31 @@ class PreviewList extends ScrollView populate: (operations) -> @destroyOperations() if @operations @operations = operations + @lastRenderedOperationIndex = 0 @empty() - - operation.index = index for operation, index in operations - operationsByPath = _.groupBy(operations, (operation) -> operation.getPath()) - for path, operations of operationsByPath - @append new PathView({path, operations, previewList: this}) + @viewsForPath = {} @show() - @find('.operation:first').addClass('selected') - @setLineNumberWidth() + @renderOperations() - setLineNumberWidth: -> - lineNumbers = @find('.line-number') - maxWidth = 0 - lineNumbers.each (index, element) -> - maxWidth = Math.max($(element).outerWidth(), maxWidth) - lineNumbers.width(maxWidth) + @find('.operation:first').addClass('selected') + + renderOperations: ({renderAll}={}) -> + renderAll ?= false + startingScrollHeight = @prop('scrollHeight') + for operation in @operations[@lastRenderedOperationIndex..] + pathView = @pathViewForPath(operation.getPath()) + pathView.addOperation(operation) + @lastRenderedOperationIndex++ + break if not renderAll and @prop('scrollHeight') >= startingScrollHeight + @pixelOverdraw and @prop('scrollHeight') > @height() + @pixelOverdraw + + pathViewForPath: (path) -> + pathView = @viewsForPath[path] + if not pathView + pathView = new PathView({path: path, previewList: this}) + @viewsForPath[path] = pathView + @append(pathView) + pathView selectNextOperation: -> selectedView = @find('.selected').view() diff --git a/src/packages/command-panel/spec/command-interpreter-spec.coffee b/src/packages/command-panel/spec/command-interpreter-spec.coffee index c4602b59f..ed1c4a702 100644 --- a/src/packages/command-panel/spec/command-interpreter-spec.coffee +++ b/src/packages/command-panel/spec/command-interpreter-spec.coffee @@ -1,6 +1,6 @@ CommandInterpreter = require 'command-panel/lib/command-interpreter' Project = require 'project' -Buffer = require 'buffer' +Buffer = require 'text-buffer' EditSession = require 'edit-session' _ = require 'underscore' diff --git a/src/packages/command-panel/spec/command-panel-spec.coffee b/src/packages/command-panel/spec/command-panel-spec.coffee index c6d9f7997..782399da3 100644 --- a/src/packages/command-panel/spec/command-panel-spec.coffee +++ b/src/packages/command-panel/spec/command-panel-spec.coffee @@ -11,7 +11,7 @@ describe "CommandPanel", -> rootView.enableKeymap() editSession = rootView.getActivePaneItem() buffer = editSession.buffer - commandPanelMain = window.loadPackage('command-panel', activateImmediately: true).mainModule + commandPanelMain = atom.activatePackage('command-panel', immediate: true).mainModule commandPanel = commandPanelMain.commandPanelView commandPanel.history = [] commandPanel.historyIndex = 0 @@ -28,11 +28,8 @@ describe "CommandPanel", -> rootView.trigger 'command-panel:toggle' expect(commandPanel.miniEditor.isFocused).toBeTruthy() - rootViewState = rootView.serialize() - rootView.deactivate() - window.rootView = RootView.deserialize(rootViewState) - rootView.attachToDom() - window.loadPackage('command-panel') + atom.deactivatePackage('command-panel') + atom.activatePackage('command-panel') expect(rootView.find('.command-panel')).not.toExist() rootView.trigger 'command-panel:toggle' @@ -55,13 +52,12 @@ describe "CommandPanel", -> expect(commandPanel.history[2]).toBe('/test3') expect(commandPanel.historyIndex).toBe(3) - rootViewState = rootView.serialize() - rootView.deactivate() - RootView.deserialize(rootViewState).attachToDom() - window.loadPackage('command-panel') - rootView.trigger 'command-panel:toggle' + atom.deactivatePackage('command-panel') + atom.activatePackage('command-panel') + rootView.trigger 'command-panel:toggle' commandPanel = rootView.find('.command-panel').view() + expect(commandPanel.history.length).toBe(2) expect(commandPanel.history[0]).toBe('/test2') expect(commandPanel.history[1]).toBe('/test3') @@ -216,39 +212,69 @@ describe "CommandPanel", -> expect(commandPanel.miniEditor.hiddenInput).not.toMatchSelector ':focus' describe "when command-panel:repeat-relative-address is triggered on the root view", -> - it "repeats the last search command if there is one", -> - rootView.trigger 'command-panel:repeat-relative-address' + describe "when there is more than one match", -> + it "repeats the last search command if there is one", -> + rootView.trigger 'command-panel:repeat-relative-address' - editSession.setCursorScreenPosition([4, 0]) + editSession.setCursorScreenPosition([4, 0]) - commandPanel.execute("/current") - expect(editSession.getSelectedBufferRange()).toEqual [[5,6], [5,13]] + commandPanel.execute("/current") + expect(editSession.getSelectedBufferRange()).toEqual [[5,6], [5,13]] - rootView.trigger 'command-panel:repeat-relative-address' - expect(editSession.getSelectedBufferRange()).toEqual [[6,6], [6,13]] + rootView.trigger 'command-panel:repeat-relative-address' + expect(editSession.getSelectedBufferRange()).toEqual [[6,6], [6,13]] - commandPanel.execute('s/r/R/g') + commandPanel.execute('s/r/R/g') - rootView.trigger 'command-panel:repeat-relative-address' - expect(editSession.getSelectedBufferRange()).toEqual [[6,34], [6,41]] + rootView.trigger 'command-panel:repeat-relative-address' + expect(editSession.getSelectedBufferRange()).toEqual [[6,34], [6,41]] - commandPanel.execute('0') - commandPanel.execute('/sort/ s/r/R/') # this contains a substitution... won't be repeated + commandPanel.execute('0') + commandPanel.execute('/sort/ s/r/R/') # this contains a substitution... won't be repeated - rootView.trigger 'command-panel:repeat-relative-address' - expect(editSession.getSelectedBufferRange()).toEqual [[3,31], [3,38]] + rootView.trigger 'command-panel:repeat-relative-address' + expect(editSession.getSelectedBufferRange()).toEqual [[3,31], [3,38]] + + describe "when there is only one match and it is selected", -> + it "maintains the current selection and plays a beep", -> + editSession.setCursorScreenPosition([0, 0]) + waitsForPromise -> + commandPanel.execute("/Array") + runs -> + expect(editSession.getSelectedBufferRange()).toEqual [[11,14], [11,19]] + spyOn($native, 'beep') + rootView.trigger 'command-panel:repeat-relative-address' + waitsFor -> + $native.beep.callCount > 0 + runs -> + expect(editSession.getSelectedBufferRange()).toEqual [[11,14], [11,19]] describe "when command-panel:repeat-relative-address-in-reverse is triggered on the root view", -> - it "it repeats the last relative address in the reverse direction", -> - rootView.trigger 'command-panel:repeat-relative-address-in-reverse' + describe "when there is more than one match", -> + it "it repeats the last relative address in the reverse direction", -> + rootView.trigger 'command-panel:repeat-relative-address-in-reverse' - editSession.setCursorScreenPosition([6, 0]) + editSession.setCursorScreenPosition([6, 0]) - commandPanel.execute("/current") - expect(editSession.getSelectedBufferRange()).toEqual [[6,6], [6,13]] + commandPanel.execute("/current") + expect(editSession.getSelectedBufferRange()).toEqual [[6,6], [6,13]] - rootView.trigger 'command-panel:repeat-relative-address-in-reverse' - expect(editSession.getSelectedBufferRange()).toEqual [[5,6], [5,13]] + rootView.trigger 'command-panel:repeat-relative-address-in-reverse' + expect(editSession.getSelectedBufferRange()).toEqual [[5,6], [5,13]] + + describe "when there is only one match and it is selected", -> + it "maintains the current selection and plays a beep", -> + editSession.setCursorScreenPosition([0, 0]) + waitsForPromise -> + commandPanel.execute("/Array") + runs -> + expect(editSession.getSelectedBufferRange()).toEqual [[11,14], [11,19]] + spyOn($native, 'beep') + rootView.trigger 'command-panel:repeat-relative-address-in-reverse' + waitsFor -> + $native.beep.callCount > 0 + runs -> + expect(editSession.getSelectedBufferRange()).toEqual [[11,14], [11,19]] describe "when command-panel:set-selection-as-regex-address is triggered on the root view", -> it "sets the @lastRelativeAddress to a RegexAddress of the current selection", -> @@ -319,13 +345,15 @@ describe "CommandPanel", -> # there shouldn't be any dangling operations after this describe "if the command is malformed", -> - it "adds and removes an error class to the command panel and does not close it", -> + it "adds and removes an error class to the command panel and does not close it or display a loading message", -> + rootView.attachToDom() rootView.trigger 'command-panel:toggle' commandPanel.miniEditor.insertText 'garbage-command!!' commandPanel.miniEditor.hiddenInput.trigger keydownEvent('enter') expect(commandPanel.parent()).toExist() expect(commandPanel).toHaveClass 'error' + expect(commandPanel.loadingMessage).toBeHidden() advanceClock 400 diff --git a/src/packages/command-panel/spec/preview-list-spec.coffee b/src/packages/command-panel/spec/preview-list-spec.coffee new file mode 100644 index 000000000..ce91de176 --- /dev/null +++ b/src/packages/command-panel/spec/preview-list-spec.coffee @@ -0,0 +1,45 @@ +RootView = require 'root-view' +CommandPanelView = require 'command-panel/lib/command-panel-view' +_ = require 'underscore' + +describe "Preview List", -> + [previewList, commandPanelMain, commandPanelView] = [] + + beforeEach -> + window.rootView = new RootView() + rootView.attachToDom() + commandPanelMain = atom.activatePackage('command-panel', immediate: true).mainModule + commandPanelView = commandPanelMain.commandPanelView + previewList = commandPanelView.previewList + rootView.trigger 'command-panel:toggle' + + describe "when the list is scrollable", -> + it "adds more operations to the DOM when `scrollBottom` nears the `pixelOverdraw`", -> + waitsForPromise -> + commandPanelView.execute('X x/so/') + + runs -> + expect(previewList.prop('scrollHeight')).toBeGreaterThan previewList.height() + previousScrollHeight = previewList.prop('scrollHeight') + previousOperationCount = previewList.find("li").length + + previewList.scrollTop(previewList.pixelOverdraw / 2) + previewList.trigger('scroll') # Not sure why scroll event isn't being triggered on it's own + expect(previewList.prop('scrollHeight')).toBe previousScrollHeight + expect(previewList.find("li").length).toBe previousOperationCount + + previewList.scrollToBottom() + previewList.trigger('scroll') # Not sure why scroll event isn't being triggered on it's own + expect(previewList.prop('scrollHeight')).toBeGreaterThan previousScrollHeight + expect(previewList.find("li").length).toBeGreaterThan previousOperationCount + + it "renders all operations if the preview items are collapsed", -> + waitsForPromise -> + commandPanelView.execute('X x/so/') + + runs -> + expect(previewList.prop('scrollHeight')).toBeGreaterThan previewList.height() + previousScrollHeight = previewList.prop('scrollHeight') + previousOperationCount = previewList.find("li").length + previewList.collapseAllPaths() + expect(previewList.find("li").length).toBeGreaterThan previousOperationCount diff --git a/static/command-panel.less b/src/packages/command-panel/stylesheets/command-panel.less similarity index 100% rename from static/command-panel.less rename to src/packages/command-panel/stylesheets/command-panel.less diff --git a/src/packages/editor-stats/lib/editor-stats-view.coffee b/src/packages/editor-stats/lib/editor-stats-view.coffee index c86ab18d8..d1a554449 100644 --- a/src/packages/editor-stats/lib/editor-stats-view.coffee +++ b/src/packages/editor-stats/lib/editor-stats-view.coffee @@ -1,5 +1,5 @@ ScrollView = require 'scroll-view' -d3 = require 'd3.v3' +d3 = require 'd3' _ = require 'underscore' $ = require 'jquery' diff --git a/src/packages/editor-stats/spec/editor-stats-spec.coffee b/src/packages/editor-stats/spec/editor-stats-spec.coffee index 9ce2360a2..582f99cfe 100644 --- a/src/packages/editor-stats/spec/editor-stats-spec.coffee +++ b/src/packages/editor-stats/spec/editor-stats-spec.coffee @@ -17,7 +17,7 @@ describe "EditorStats", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - editorStats = window.loadPackage('editor-stats').mainModule.stats + editorStats = atom.activatePackage('editor-stats').mainModule.stats describe "when a keyup event is triggered", -> beforeEach -> diff --git a/src/packages/editor-stats/stylesheets/editor-stats.less b/src/packages/editor-stats/stylesheets/editor-stats.less index 26efaafde..442d0bc43 100644 --- a/src/packages/editor-stats/stylesheets/editor-stats.less +++ b/src/packages/editor-stats/stylesheets/editor-stats.less @@ -2,7 +2,6 @@ padding: 5px; box-sizing: border-box; border-top: 1px solid rgba(255, 255, 255, 0.05); - z-index: 9999; } .editor-stats { diff --git a/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee b/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee index 5212b3c2f..07ba5b5ec 100644 --- a/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee +++ b/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee @@ -2,7 +2,7 @@ SelectList = require 'select-list' _ = require 'underscore' $ = require 'jquery' -fs = require 'fs' +fs = require 'fs-utils' LoadPathsTask = require './load-paths-task' module.exports = @@ -139,7 +139,7 @@ class FuzzyFinderView extends SelectList @setArray(paths) populateProjectPaths: (options = {}) -> - if @projectPaths?.length > 0 + if @projectPaths? listedItems = if options.filter? @projectPaths.filter (path) -> @@ -156,21 +156,15 @@ class FuzzyFinderView extends SelectList callback = (paths) => @projectPaths = paths @reloadProjectPaths = false - listedItems = - if options.filter? - @projectPaths.filter (path) -> - path.indexOf(options.filter) >= 0 - else - @projectPaths - - @setArray(listedItems) - options.done(listedItems) if options.done? + @populateProjectPaths(options) @loadPathsTask = new LoadPathsTask(callback) @loadPathsTask.start() populateOpenBufferPaths: -> - editSessions = project.getEditSessions().filter (editSession)-> + editSessions = project.getEditSessions().filter (editSession) -> editSession.getPath()? + editSessions = _.uniq editSessions, (editSession) -> + editSession.getPath() editSessions = _.sortBy editSessions, (editSession) => if editSession is rootView.getActivePaneItem() diff --git a/src/packages/fuzzy-finder/lib/load-paths-handler.coffee b/src/packages/fuzzy-finder/lib/load-paths-handler.coffee deleted file mode 100644 index fcae29e8a..000000000 --- a/src/packages/fuzzy-finder/lib/load-paths-handler.coffee +++ /dev/null @@ -1,24 +0,0 @@ -fs = require 'fs' -_ = require 'underscore' - -module.exports = - loadPaths: (rootPath, ignoredNames, excludeGitIgnoredPaths) -> - if excludeGitIgnoredPaths - Git = require 'git' - repo = Git.open(rootPath, refreshOnWindowFocus: false) - - paths = [] - isIgnored = (path) -> - path = path.substring(rootPath.length + 1) - for segment in path.split('/') - return true if _.contains(ignoredNames, segment) - repo?.isPathIgnored(fs.join(rootPath, path)) - onFile = (path) -> - paths.push(path) unless isIgnored(path) - onDirectory = (path) -> - not isIgnored(path) - fs.traverseTree(rootPath, onFile, onDirectory) - - repo?.destroy() - - callTaskMethod('pathsLoaded', paths) diff --git a/src/packages/fuzzy-finder/lib/load-paths-task.coffee b/src/packages/fuzzy-finder/lib/load-paths-task.coffee index f2ff851b6..60a716688 100644 --- a/src/packages/fuzzy-finder/lib/load-paths-task.coffee +++ b/src/packages/fuzzy-finder/lib/load-paths-task.coffee @@ -1,17 +1,33 @@ -Task = require 'task' +_ = require 'underscore' +fs = require 'fs-utils' module.exports = -class LoadPathsTask extends Task - constructor: (@callback) -> - super('fuzzy-finder/lib/load-paths-handler') +class LoadPathsTask + aborted: false - started: -> + constructor: (@callback) -> + + start: -> + rootPath = project.getPath() ignoredNames = config.get('fuzzyFinder.ignoredNames') ? [] ignoredNames = ignoredNames.concat(config.get('core.ignoredNames') ? []) - excludeGitIgnoredPaths = config.get('core.hideGitIgnoredFiles') - rootPath = project.getPath() - @callWorkerMethod('loadPaths', rootPath, ignoredNames, excludeGitIgnoredPaths) + ignoreGitIgnoredFiles = config.get('core.hideGitIgnoredFiles') - pathsLoaded: (paths) -> - @done() - @callback(paths) + paths = [] + isIgnored = (path) -> + for segment in path.split('/') + return true if _.contains(ignoredNames, segment) + ignoreGitIgnoredFiles and git?.isPathIgnored(fs.join(rootPath, path)) + onFile = (path) -> + return if @aborted + path = path.substring(rootPath.length + 1) + paths.push(path) unless isIgnored(path) + onDirectory = (path) => + not @aborted and not isIgnored(path.substring(rootPath.length + 1)) + onDone = => + @callback(paths) unless @aborted + + fs.traverseTree(rootPath, onFile, onDirectory, onDone) + + abort: -> + @aborted = true diff --git a/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee b/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee index bde11cca9..15c89721e 100644 --- a/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee +++ b/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee @@ -4,7 +4,7 @@ LoadPathsTask = require 'fuzzy-finder/lib/load-paths-task' _ = require 'underscore' $ = require 'jquery' {$$} = require 'space-pen' -fs = require 'fs' +fs = require 'fs-utils' describe 'FuzzyFinder', -> [finderView] = [] @@ -13,7 +13,7 @@ describe 'FuzzyFinder', -> window.rootView = new RootView rootView.open('sample.js') rootView.enableKeymap() - finderView = window.loadPackage("fuzzy-finder").mainModule.createView() + finderView = atom.activatePackage("fuzzy-finder").mainModule.createView() describe "file-finder behavior", -> describe "toggling", -> @@ -43,13 +43,14 @@ describe 'FuzzyFinder', -> it "shows all relative file paths for the current project and selects the first", -> rootView.attachToDom() finderView.maxItems = Infinity + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:toggle-file-finder' paths = null expect(finderView.find(".loading")).toBeVisible() expect(finderView.find(".loading")).toHaveText "Indexing..." waitsFor "all project paths to load", 5000, -> - if finderView.projectPaths?.length > 0 + unless finderView.reloadProjectPaths paths = finderView.projectPaths true @@ -142,8 +143,8 @@ describe 'FuzzyFinder', -> rootView.trigger 'fuzzy-finder:toggle-buffer-finder' rootView.open() - states = rootView.serialize().packages - states = _.map states['fuzzy-finder'], (path, time) -> [ path, time ] + atom.deactivatePackage('fuzzy-finder') + states = _.map atom.getPackageState('fuzzy-finder'), (path, time) -> [ path, time ] states = _.sortBy states, (path, time) -> -time paths = [ 'sample-with-tabs.coffee', 'sample.txt', 'sample.js' ] @@ -165,6 +166,13 @@ describe 'FuzzyFinder', -> rootView.trigger 'fuzzy-finder:toggle-buffer-finder' expect(rootView.find('.fuzzy-finder')).not.toExist() + describe "when multiple sessions are opened on the same path", -> + it "does not display duplicates for that path in the list", -> + rootView.open 'sample.js' + rootView.getActivePane().splitRight() + rootView.trigger 'fuzzy-finder:toggle-buffer-finder' + expect(_.pluck(finderView.list.children('li'), 'outerText')).toEqual ['sample.js'] + describe "when a path selection is confirmed", -> [editor1, editor2] = [] @@ -271,6 +279,7 @@ describe 'FuzzyFinder', -> describe "cached file paths", -> it "caches file paths after first time", -> spyOn(LoadPathsTask.prototype, "start").andCallThrough() + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> @@ -290,6 +299,7 @@ describe 'FuzzyFinder', -> it "doesn't cache buffer paths", -> spyOn(project, "getEditSessions").andCallThrough() + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:toggle-buffer-finder' waitsFor -> @@ -309,6 +319,7 @@ describe 'FuzzyFinder', -> it "busts the cache when the window gains focus", -> spyOn(LoadPathsTask.prototype, "start").andCallThrough() + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> @@ -325,6 +336,7 @@ describe 'FuzzyFinder', -> describe "path ignoring", -> it "ignores paths that match entries in config.fuzzyFinder.ignoredNames", -> config.set("fuzzyFinder.ignoredNames", ["tree-view.js"]) + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:toggle-file-finder' finderView.maxItems = Infinity @@ -343,6 +355,7 @@ describe 'FuzzyFinder', -> it "opens the fuzzy finder window when there are multiple matches", -> editor.setText("sample") + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:find-under-cursor' waitsFor -> @@ -354,6 +367,7 @@ describe 'FuzzyFinder', -> it "opens a file directly when there is a single match", -> editor.setText("sample.txt") + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:find-under-cursor' openedPath = null @@ -367,10 +381,11 @@ describe 'FuzzyFinder', -> expect(finderView).not.toBeVisible() expect(openedPath).toBe "sample.txt" - it "displays error when the word under the cursor doesn't match any files", -> + it "displays an error when the word under the cursor doesn't match any files", -> editor.setText("moogoogaipan") editor.setCursorBufferPosition([0,5]) + jasmine.unspy(window, "setTimeout") rootView.trigger 'fuzzy-finder:find-under-cursor' waitsFor -> diff --git a/static/fuzzy-finder.less b/src/packages/fuzzy-finder/stylesheets/fuzzy-finder.less similarity index 100% rename from static/fuzzy-finder.less rename to src/packages/fuzzy-finder/stylesheets/fuzzy-finder.less diff --git a/src/packages/gfm.tmbundle/Preferences/indent.cson b/src/packages/gfm.tmbundle/Preferences/indent.cson deleted file mode 100644 index 113cdcb96..000000000 --- a/src/packages/gfm.tmbundle/Preferences/indent.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'Indent' -'scope': 'source.gfm' -'settings': - 'increaseIndentPattern': '^\\s*([\\*\\+-])[ \\t]+' diff --git a/src/packages/gfm.tmbundle/Snippets/bold.cson b/src/packages/gfm.tmbundle/Snippets/bold.cson deleted file mode 100644 index f42f3b0e6..000000000 --- a/src/packages/gfm.tmbundle/Snippets/bold.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'bold text' -'scope': 'source.gfm' -'tabTrigger': 'b' -'content': '**$1**$0' diff --git a/src/packages/gfm.tmbundle/Snippets/code.cson b/src/packages/gfm.tmbundle/Snippets/code.cson deleted file mode 100644 index 14002c848..000000000 --- a/src/packages/gfm.tmbundle/Snippets/code.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'code block' -'scope': 'source.gfm' -'tabTrigger': 'code' -'content': '```$1\n$2\n```$0' diff --git a/src/packages/gfm.tmbundle/Snippets/img.cson b/src/packages/gfm.tmbundle/Snippets/img.cson deleted file mode 100644 index ea5474167..000000000 --- a/src/packages/gfm.tmbundle/Snippets/img.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'embedded image' -'scope': 'source.gfm' -'tabTrigger': 'img' -'content': '![$1]($2)$0' diff --git a/src/packages/gfm.tmbundle/Snippets/italic.cson b/src/packages/gfm.tmbundle/Snippets/italic.cson deleted file mode 100644 index eccc243da..000000000 --- a/src/packages/gfm.tmbundle/Snippets/italic.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'italic text' -'scope': 'source.gfm' -'tabTrigger': 'i' -'content': '*$1*$0' diff --git a/src/packages/gfm.tmbundle/Snippets/link.cson b/src/packages/gfm.tmbundle/Snippets/link.cson deleted file mode 100644 index cbbe638a6..000000000 --- a/src/packages/gfm.tmbundle/Snippets/link.cson +++ /dev/null @@ -1,4 +0,0 @@ -'name': 'link' -'scope': 'source.gfm' -'tabTrigger': 'l' -'content': '[$1]($2)$0' diff --git a/src/packages/gfm.tmbundle/Syntaxes/gfm.cson b/src/packages/gfm/grammars/gfm.cson similarity index 99% rename from src/packages/gfm.tmbundle/Syntaxes/gfm.cson rename to src/packages/gfm/grammars/gfm.cson index 1f6a5a3f7..be815f5ca 100644 --- a/src/packages/gfm.tmbundle/Syntaxes/gfm.cson +++ b/src/packages/gfm/grammars/gfm.cson @@ -7,6 +7,7 @@ 'mkdown' 'ron' ] + 'patterns': [ { 'match': '(?:^|\\s)(\\*\\*[^\\*]+\\*\\*)' diff --git a/src/packages/gfm/scoped-properties/gfm.cson b/src/packages/gfm/scoped-properties/gfm.cson new file mode 100644 index 000000000..a9be1a2a4 --- /dev/null +++ b/src/packages/gfm/scoped-properties/gfm.cson @@ -0,0 +1,3 @@ +'.source.gfm': + 'editor': + 'increaseIndentPattern': '^\\s*([\\*\\+-])[ \\t]+' diff --git a/src/packages/gfm/snippets/gfm.cson b/src/packages/gfm/snippets/gfm.cson new file mode 100644 index 000000000..d3d751922 --- /dev/null +++ b/src/packages/gfm/snippets/gfm.cson @@ -0,0 +1,16 @@ +'.source.gfm': + 'bold text': + prefix: 'b' + body: '**$1**$0' + 'embedded image': + prefix: 'img' + body: '![$1]($2)$0' + 'italic text': + prefix: 'i' + body: '*$1*$0' + 'link': + prefix: 'l' + body: '[$1]($2)$0' + 'code': + prefix: 'code' + body: '```$1\n$2\n```$0' diff --git a/src/packages/gfm.tmbundle/spec/gfm-spec.coffee b/src/packages/gfm/spec/gfm-spec.coffee similarity index 96% rename from src/packages/gfm.tmbundle/spec/gfm-spec.coffee rename to src/packages/gfm/spec/gfm-spec.coffee index 97bc98300..ea579187e 100644 --- a/src/packages/gfm.tmbundle/spec/gfm-spec.coffee +++ b/src/packages/gfm/spec/gfm-spec.coffee @@ -4,13 +4,13 @@ describe "GitHub Flavored Markdown grammar", -> grammar = null beforeEach -> - spyOn(syntax, "addGrammar") - pack = new TextMatePackage(require.resolve("gfm.tmbundle")) - pack.load() - grammar = pack.grammars[0] + spyOn(syntax, "addGrammar").andCallThrough() + atom.activatePackage("gfm") + expect(syntax.addGrammar).toHaveBeenCalled() + grammar = syntax.addGrammar.argsForCall[0][0] it "parses the grammar", -> - expect(grammar).toBeTruthy() + expect(grammar).toBeDefined() expect(grammar.scopeName).toBe "source.gfm" it "tokenizes horizontal rules", -> diff --git a/src/packages/gists/lib/gists.coffee b/src/packages/gists/lib/gists.coffee index 6df96a01d..cada1d582 100644 --- a/src/packages/gists/lib/gists.coffee +++ b/src/packages/gists/lib/gists.coffee @@ -8,7 +8,7 @@ class Gists constructor: -> rootView.command 'gist:create', '.editor', => @createGist() - createGist: (editor) -> + createGist: -> editor = rootView.getActiveView() return unless editor? diff --git a/src/packages/gists/spec/gists-spec.coffee b/src/packages/gists/spec/gists-spec.coffee index 3091f8ed6..58866b892 100644 --- a/src/packages/gists/spec/gists-spec.coffee +++ b/src/packages/gists/spec/gists-spec.coffee @@ -7,7 +7,7 @@ describe "Gists package", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - window.loadPackage('gists') + atom.activatePackage('gists') editor = rootView.getActiveView() spyOn($, 'ajax') diff --git a/src/packages/grammar-selector/keymaps/grammar-selector.cson b/src/packages/grammar-selector/keymaps/grammar-selector.cson new file mode 100644 index 000000000..07e5050bd --- /dev/null +++ b/src/packages/grammar-selector/keymaps/grammar-selector.cson @@ -0,0 +1,3 @@ +'.editor': + 'meta-L': 'grammar-selector:show' + diff --git a/src/app/grammar-view.coffee b/src/packages/grammar-selector/lib/grammar-selector.coffee similarity index 67% rename from src/app/grammar-view.coffee rename to src/packages/grammar-selector/lib/grammar-selector.coffee index 22963375b..ca0aa828b 100644 --- a/src/app/grammar-view.coffee +++ b/src/packages/grammar-selector/lib/grammar-selector.coffee @@ -1,18 +1,23 @@ SelectList = require 'select-list' +Editor = require 'editor' {$$} = require 'space-pen' module.exports = -class GrammarView extends SelectList +class GrammarSelector extends SelectList + @viewClass: -> "#{super} grammar-selector from-top overlay mini" - @viewClass: -> "#{super} grammar-view from-top overlay mini" + @activate: -> + rootView.command 'grammar-selector:show', '.editor', => new GrammarSelector() filterKey: 'name' - initialize: (@editor) -> + initialize: -> + @editor = rootView.getActiveView() + return unless @editor instanceof Editor @currentGrammar = @editor.getGrammar() @path = @editor.getPath() @autoDetect = name: 'Auto Detect' - @command 'editor:select-grammar', => + @command 'grammar-selector:show', => @cancel() false super @@ -48,13 +53,12 @@ class GrammarView extends SelectList confirmed: (grammar) -> @cancel() if grammar is @autoDetect - project.removeGrammarOverrideForPath(@path) + syntax.clearGrammarOverrideForPath(@path) else - project.addGrammarOverrideForPath(@path, grammar) + syntax.setGrammarOverrideForPath(@path, grammar.scopeName) @editor.reloadGrammar() attach: -> super - rootView.append(this) - @miniEditor.focus() + @miniEditor.focus() \ No newline at end of file diff --git a/src/packages/grammar-selector/package.cson b/src/packages/grammar-selector/package.cson new file mode 100644 index 000000000..99390e3bc --- /dev/null +++ b/src/packages/grammar-selector/package.cson @@ -0,0 +1,2 @@ +'main': 'lib/grammar-selector' +'activationEvents': ['grammar-selector:show'] diff --git a/spec/app/grammar-view-spec.coffee b/src/packages/grammar-selector/spec/grammar-selector-spec.coffee similarity index 63% rename from spec/app/grammar-view-spec.coffee rename to src/packages/grammar-selector/spec/grammar-selector-spec.coffee index 45157aab0..db4fa262c 100644 --- a/spec/app/grammar-view-spec.coffee +++ b/src/packages/grammar-selector/spec/grammar-selector-spec.coffee @@ -1,12 +1,15 @@ +GrammarSelector = require '../lib/grammar-selector' RootView = require 'root-view' -GrammarView = require 'grammar-view' _ = require 'underscore' -describe "GrammarView", -> +describe "GrammarSelector", -> [editor, textGrammar, jsGrammar] = [] beforeEach -> window.rootView = new RootView + atom.activatePackage('grammar-selector') + atom.activatePackage('text.tmbundle', sync: true) + atom.activatePackage('javascript.tmbundle', sync: true) rootView.open('sample.js') editor = rootView.getActiveView() textGrammar = _.find syntax.grammars, (grammar) -> grammar.name is 'Plain Text' @@ -15,10 +18,10 @@ describe "GrammarView", -> expect(jsGrammar).toBeTruthy() expect(editor.getGrammar()).toBe jsGrammar - describe "when editor:select-grammar is toggled", -> + describe "when grammar-selector:show is triggered", -> it "displays a list of all the available grammars", -> - editor.trigger 'editor:select-grammar' - grammarView = rootView.find('.grammar-view').view() + editor.trigger 'grammar-selector:show' + grammarView = rootView.find('.grammar-selector').view() expect(grammarView).toExist() grammars = syntax.grammars expect(grammarView.list.children('li').length).toBe grammars.length + 1 @@ -26,19 +29,19 @@ describe "GrammarView", -> describe "when a grammar is selected", -> it "sets the new grammar on the editor", -> - editor.trigger 'editor:select-grammar' - grammarView = rootView.find('.grammar-view').view() + editor.trigger 'grammar-selector:show' + grammarView = rootView.find('.grammar-selector').view() grammarView.confirmed(textGrammar) expect(editor.getGrammar()).toBe textGrammar describe "when auto-detect is selected", -> it "restores the auto-detected grammar on the editor", -> - editor.trigger 'editor:select-grammar' - grammarView = rootView.find('.grammar-view').view() + editor.trigger 'grammar-selector:show' + grammarView = rootView.find('.grammar-selector').view() grammarView.confirmed(textGrammar) expect(editor.getGrammar()).toBe textGrammar - editor.trigger 'editor:select-grammar' - grammarView = rootView.find('.grammar-view').view() + editor.trigger 'grammar-selector:show' + grammarView = rootView.find('.grammar-selector').view() grammarView.confirmed(grammarView.array[0]) expect(editor.getGrammar()).toBe jsGrammar diff --git a/src/packages/markdown-preview/lib/markdown-preview-view.coffee b/src/packages/markdown-preview/lib/markdown-preview-view.coffee index a65c09eba..5b88545ac 100644 --- a/src/packages/markdown-preview/lib/markdown-preview-view.coffee +++ b/src/packages/markdown-preview/lib/markdown-preview-view.coffee @@ -1,4 +1,4 @@ -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' ScrollView = require 'scroll-view' {$$$} = require 'space-pen' @@ -29,6 +29,9 @@ class MarkdownPreviewView extends ScrollView getUri: -> "markdown-preview:#{@buffer.getPath()}" + getPath: -> + @buffer.getPath() + setErrorHtml: -> @html $$$ -> @h2 'Previewing Markdown Failed' diff --git a/src/packages/markdown-preview/lib/markdown-preview.coffee b/src/packages/markdown-preview/lib/markdown-preview.coffee index b30bbb621..457984f1e 100644 --- a/src/packages/markdown-preview/lib/markdown-preview.coffee +++ b/src/packages/markdown-preview/lib/markdown-preview.coffee @@ -22,4 +22,4 @@ module.exports = nextPane.showItem(new MarkdownPreviewView(editSession.buffer)) else activePane.splitRight(new MarkdownPreviewView(editSession.buffer)) - activePane.focus() \ No newline at end of file + activePane.focus() diff --git a/src/packages/markdown-preview/spec/markdown-preview-spec.coffee b/src/packages/markdown-preview/spec/markdown-preview-spec.coffee index 9a7ed6e33..1bcf984ad 100644 --- a/src/packages/markdown-preview/spec/markdown-preview-spec.coffee +++ b/src/packages/markdown-preview/spec/markdown-preview-spec.coffee @@ -6,7 +6,7 @@ describe "MarkdownPreview package", -> beforeEach -> project.setPath(project.resolve('markdown')) window.rootView = new RootView - window.loadPackage("markdown-preview", activateImmediately: true) + atom.activatePackage("markdown-preview", immediate: true) spyOn(MarkdownPreviewView.prototype, 'fetchRenderedMarkdown') describe "markdown-preview:show", -> diff --git a/src/packages/package-generator/lib/package-generator-view.coffee b/src/packages/package-generator/lib/package-generator-view.coffee index a38315446..63f07890f 100644 --- a/src/packages/package-generator/lib/package-generator-view.coffee +++ b/src/packages/package-generator/lib/package-generator-view.coffee @@ -2,7 +2,7 @@ Editor = require 'editor' $ = require 'jquery' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' module.exports = class PackageGeneratorView extends View @@ -56,7 +56,7 @@ class PackageGeneratorView extends View true createPackageFiles: -> - templatePath = require.resolve(fs.join("package-generator", "template")) + templatePath = fs.resolveOnLoadPath(fs.join("package-generator", "template")) packageName = fs.base(@getPackagePath()) for path in fs.listTree(templatePath) diff --git a/src/packages/package-generator/spec/package-generator-spec.coffee b/src/packages/package-generator/spec/package-generator-spec.coffee index c9dd0c727..87d57bbdd 100644 --- a/src/packages/package-generator/spec/package-generator-spec.coffee +++ b/src/packages/package-generator/spec/package-generator-spec.coffee @@ -1,5 +1,5 @@ RootView = require 'root-view' -fs = require 'fs' +fs = require 'fs-utils' describe 'Package Generator', -> [packageGenerator] = [] @@ -7,7 +7,7 @@ describe 'Package Generator', -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - window.loadPackage("package-generator") + atom.activatePackage("package-generator") describe "when package-generator:generate is triggered", -> it "displays a miniEditor", -> diff --git a/src/packages/package-generator/template/spec/__package-name__-view-spec.coffee.template b/src/packages/package-generator/template/spec/__package-name__-view-spec.coffee.template index a8b62caf7..dc342839d 100644 --- a/src/packages/package-generator/template/spec/__package-name__-view-spec.coffee.template +++ b/src/packages/package-generator/template/spec/__package-name__-view-spec.coffee.template @@ -10,7 +10,7 @@ fdescribe "__PackageName__View", -> beforeEach -> window.rootView = new RootView - __packageName__ = window.loadPackage('__packageName__', activateImmediately: true) + __packageName__ = atom.activatePackage('__packageName__', immediate: true) describe "when the __package-name__:toggle event is triggered", -> it "attaches and then detaches the view", -> diff --git a/src/packages/snippets/lib/load-snippets-handler.coffee b/src/packages/snippets/lib/load-snippets-handler.coffee deleted file mode 100644 index c897330dc..000000000 --- a/src/packages/snippets/lib/load-snippets-handler.coffee +++ /dev/null @@ -1,55 +0,0 @@ -fs = require 'fs' -TextMatePackage = require 'text-mate-package' -SnippetBodyParser = require './snippet-body-parser' - -module.exports = - snippetsLoaded: (snippets) -> - for snippet in snippets - for selector, snippetsByName of snippet - for name, attributes of snippetsByName - attributes.bodyTree = SnippetBodyParser.parse(attributes.body) - callTaskMethod('snippetsLoaded', snippets) - - loadTextMateSnippets: (path) -> - snippetsDirPath = fs.join(path, 'Snippets') - snippets = [] - - for snippetsPath in fs.list(snippetsDirPath) - logWarning = -> - console.warn "Error reading TextMate snippets file '#{snippetsPath}'" - - continue if fs.base(snippetsPath).indexOf('.') is 0 - try - if fs.isObjectPath(snippetsPath) and object = fs.readObject(snippetsPath) - snippets.push(object) - else if object = fs.readPlist(snippetsPath) - snippets.push(object) - else - logWarning() - catch e - logWarning() - - @snippetsLoaded(@translateTextmateSnippets(snippets)) - - loadAtomSnippets: (path) -> - snippetsDirPath = fs.join(path, 'snippets') - snippets = [] - for snippetsPath in fs.list(snippetsDirPath) - continue if fs.base(snippetsPath).indexOf('.') is 0 - try - snippets.push(fs.readObject(snippetsPath)) - catch e - console.warn "Error reading snippets file '#{snippetsPath}'" - @snippetsLoaded(snippets) - - translateTextmateSnippets: (tmSnippets) -> - atomSnippets = {} - for { scope, name, content, tabTrigger } in tmSnippets - if scope - scope = TextMatePackage.cssSelectorFromScopeSelector(scope) - else - scope = '*' - - snippetsForScope = (atomSnippets[scope] ?= {}) - snippetsForScope[name] = { prefix: tabTrigger, body: content } - [atomSnippets] diff --git a/src/packages/snippets/lib/load-snippets-task.coffee b/src/packages/snippets/lib/load-snippets-task.coffee deleted file mode 100644 index 98b73b470..000000000 --- a/src/packages/snippets/lib/load-snippets-task.coffee +++ /dev/null @@ -1,34 +0,0 @@ -Task = require 'task' -TextMatePackage = require 'text-mate-package' - -module.exports = -class LoadSnippetsTask extends Task - constructor: (@snippets) -> - super('snippets/lib/load-snippets-handler') - @packages = atom.getLoadedPackages() - @packages.push(path: config.configDirPath) - - started: -> - @loadNextPackageSnippets() - - loadNextPackageSnippets: -> - unless @packages.length - @done() - @snippets.loaded = true - return - - @packageBeingLoaded = @packages.shift() - if @packageBeingLoaded instanceof TextMatePackage - @loadTextMateSnippets(@packageBeingLoaded.path) - else - @loadAtomSnippets(@packageBeingLoaded.path) - - loadAtomSnippets: (path) -> - @callWorkerMethod('loadAtomSnippets', path) - - loadTextMateSnippets: (path) -> - @callWorkerMethod('loadTextMateSnippets', path) - - snippetsLoaded: (snippets) -> - @snippets.add(snippet) for snippet in snippets - @loadNextPackageSnippets() diff --git a/src/packages/snippets/lib/snippet-body-parser.coffee b/src/packages/snippets/lib/snippet-body-parser.coffee index 0239fee3f..f4c3f99f7 100644 --- a/src/packages/snippets/lib/snippet-body-parser.coffee +++ b/src/packages/snippets/lib/snippet-body-parser.coffee @@ -1,4 +1,4 @@ PEG = require 'pegjs' -fs = require 'fs' +fs = require 'fs-utils' grammarSrc = fs.read(require.resolve('./snippet-body.pegjs')) module.exports = PEG.buildParser(grammarSrc, trackLineAndColumn: true) diff --git a/src/packages/snippets/lib/snippet-expansion.coffee b/src/packages/snippets/lib/snippet-expansion.coffee index 7c27222b8..68f9935af 100644 --- a/src/packages/snippets/lib/snippet-expansion.coffee +++ b/src/packages/snippets/lib/snippet-expansion.coffee @@ -27,7 +27,7 @@ class SnippetExpansion return if @settingTabStop or bufferChanged oldTabStops = @tabStopsForBufferPosition(oldBufferPosition) newTabStops = @tabStopsForBufferPosition(newBufferPosition) - @destroy() unless _.intersect(oldTabStops, newTabStops).length + @destroy() unless _.intersection(oldTabStops, newTabStops).length placeTabStopMarkers: (startPosition, tabStopRanges) -> @tabStopMarkers = tabStopRanges.map ({start, end}) => diff --git a/src/packages/snippets/lib/snippets.coffee b/src/packages/snippets/lib/snippets.coffee index cd8e279d9..a2e785adf 100644 --- a/src/packages/snippets/lib/snippets.coffee +++ b/src/packages/snippets/lib/snippets.coffee @@ -1,9 +1,12 @@ AtomPackage = require 'atom-package' fs = require 'fs' +fsUtils = require 'fs-utils' _ = require 'underscore' SnippetExpansion = require './snippet-expansion' Snippet = require './snippet' -LoadSnippetsTask = require './load-snippets-task' +TextMatePackage = require 'text-mate-package' +CSON = require 'cson' +async = require 'async' module.exports = snippetsByExtension: {} @@ -16,22 +19,85 @@ module.exports = @enableSnippetsInEditor(editor) if editor.attached deactivate: -> - @loadSnippetsTask?.abort() loadAll: -> - @loadSnippetsTask = new LoadSnippetsTask(this) - @loadSnippetsTask.start() + packages = atom.getLoadedPackages() + packages.push(path: config.configDirPath) + async.eachSeries packages, @loadSnippetsFromPackage.bind(this), @doneLoading.bind(this) - loadDirectory: (snippetsDirPath) -> - for snippetsPath in fs.list(snippetsDirPath) when fs.base(snippetsPath).indexOf('.') isnt 0 - snippets.loadFile(snippetsPath) + doneLoading: -> + @loaded = true - loadFile: (snippetsPath) -> - try - snippets = fs.readObject(snippetsPath) - catch e - console.warn "Error reading snippets file '#{snippetsPath}'" - @add(snippets) + loadSnippetsFromPackage: (pack, done) -> + if pack instanceof TextMatePackage + @loadTextMateSnippets(pack.path, done) + else + @loadAtomSnippets(pack.path, done) + + loadAtomSnippets: (path, done) -> + snippetsDirPath = fsUtils.join(path, 'snippets') + return done() unless fsUtils.isDirectory(snippetsDirPath) + + loadSnippetFile = (filename, done) => + return done() if filename.indexOf('.') is 0 + filepath = fsUtils.join(snippetsDirPath, filename) + CSON.readObjectAsync filepath, (err, object) => + if err + console.warn "Error reading snippets file '#{filepath}': #{err.stack}" + else + @add(object) + done() + + fs.readdir snippetsDirPath, (err, paths) -> + async.eachSeries(paths, loadSnippetFile, done) + + loadTextMateSnippets: (path, done) -> + snippetsDirPath = fsUtils.join(path, 'Snippets') + return done() unless fsUtils.isDirectory(snippetsDirPath) + + loadSnippetFile = (filename, done) => + return done() if filename.indexOf('.') is 0 + + filepath = fsUtils.join(snippetsDirPath, filename) + + logError = (err) -> + console.warn "Error reading snippets file '#{filepath}': #{err.stack ? err}" + + try + readObject = + if CSON.isObjectPath(filepath) + CSON.readObjectAsync.bind(CSON) + else + fsUtils.readPlistAsync.bind(fsUtils) + + readObject filepath, (err, object) => + try + if err + logError(err) + else + @add(@translateTextmateSnippet(object)) + catch err + logError(err) + finally + done() + catch err + logError(err) + done() + + fs.readdir snippetsDirPath, (err, paths) -> + if err + console.warn err + return done() + async.eachSeries(paths, loadSnippetFile, done) + + translateTextmateSnippet: ({ scope, name, content, tabTrigger }) -> + scope = syntax.cssSelectorFromScopeSelector(scope) if scope + scope ?= '*' + snippetsByScope = {} + snippetsByName = {} + snippetsByScope[scope] = snippetsByName + snippetsByName[name] = { prefix: tabTrigger, body: content } + snippetsByScope add: (snippetsBySelector) -> for selector, snippetsByName of snippetsBySelector diff --git a/src/packages/snippets/spec/snippets-spec.coffee b/src/packages/snippets/spec/snippets-spec.coffee index b77b2d80b..2236757e7 100644 --- a/src/packages/snippets/spec/snippets-spec.coffee +++ b/src/packages/snippets/spec/snippets-spec.coffee @@ -1,25 +1,22 @@ Snippet = require 'snippets/lib/snippet' -LoadSnippetsTask = require 'snippets/lib/load-snippets-task' RootView = require 'root-view' -Buffer = require 'buffer' +Buffer = require 'text-buffer' Editor = require 'editor' _ = require 'underscore' -fs = require 'fs' +fs = require 'fs-utils' Package = require 'package' describe "Snippets extension", -> [buffer, editor, editSession] = [] beforeEach -> + atom.activatePackage('javascript.tmbundle', sync: true) window.rootView = new RootView rootView.open('sample.js') - spyOn(LoadSnippetsTask.prototype, 'start') - packageWithSnippets = window.loadPackage("package-with-snippets") + packageWithSnippets = atom.loadPackage("package-with-snippets") - spyOn(atom, "getLoadedPackages").andCallFake -> - window.textMatePackages.concat([packageWithSnippets]) - - window.loadPackage("snippets") + spyOn(require("snippets/lib/snippets"), 'loadAll') + atom.activatePackage("snippets") editor = rootView.getActiveView() editSession = rootView.getActivePaneItem() @@ -239,12 +236,16 @@ describe "Snippets extension", -> describe "snippet loading", -> beforeEach -> - jasmine.unspy(LoadSnippetsTask.prototype, 'start') - spyOn(LoadSnippetsTask.prototype, 'loadAtomSnippets').andCallFake -> @snippetsLoaded({}) - spyOn(LoadSnippetsTask.prototype, 'loadTextMateSnippets').andCallFake -> @snippetsLoaded({}) + atom.loadPackage('package-with-broken-snippets.tmbundle', sync: true) + atom.loadPackage('package-with-snippets') + + jasmine.unspy(window, "setTimeout") + jasmine.unspy(snippets, 'loadAll') + spyOn(snippets, 'loadAtomSnippets').andCallFake (path, done) -> done() + spyOn(snippets, 'loadTextMateSnippets').andCallFake (path, done) -> done() it "loads non-hidden snippet files from all atom packages with snippets directories, logging a warning if a file can't be parsed", -> - jasmine.unspy(LoadSnippetsTask.prototype, 'loadAtomSnippets') + jasmine.unspy(snippets, 'loadAtomSnippets') spyOn(console, 'warn') snippets.loaded = false snippets.loadAll() @@ -259,7 +260,7 @@ describe "Snippets extension", -> expect(console.warn.calls.length).toBe 1 it "loads snippets from all TextMate packages with snippets", -> - jasmine.unspy(LoadSnippetsTask.prototype, 'loadTextMateSnippets') + jasmine.unspy(snippets, 'loadTextMateSnippets') spyOn(console, 'warn') snippets.loaded = false snippets.loadAll() @@ -281,37 +282,6 @@ describe "Snippets extension", -> expect(console.warn).toHaveBeenCalled() expect(console.warn.calls.length).toBe 1 - it "terminates the worker when loading completes", -> - jasmine.unspy(LoadSnippetsTask.prototype, 'loadAtomSnippets') - spyOn(console, "warn") - spyOn(Worker.prototype, 'terminate').andCallThrough() - snippets.loaded = false - snippets.loadAll() - - waitsFor "all snippets to load", 5000, -> snippets.loaded - - runs -> - expect(console.warn).toHaveBeenCalled() - expect(console.warn.argsForCall[0]).toMatch /Error reading snippets file '.*?\/spec\/fixtures\/packages\/package-with-snippets\/snippets\/junk-file'/ - expect(Worker.prototype.terminate).toHaveBeenCalled() - expect(Worker.prototype.terminate.calls.length).toBe 1 - - it "loads CSON snippets from TextMate packages", -> - jasmine.unspy(LoadSnippetsTask.prototype, 'loadTextMateSnippets') - snippets.loaded = false - task = new LoadSnippetsTask(snippets) - task.packages = [Package.build(project.resolve('packages/package-with-a-cson-grammar.tmbundle'))] - task.start() - - waitsFor "CSON snippets to load", 5000, -> snippets.loaded - - runs -> - snippet = syntax.getProperty(['.source.alot'], 'snippets.really') - expect(snippet).toBeTruthy() - expect(snippet.prefix).toBe 'really' - expect(snippet.name).toBe 'Really' - expect(snippet.body).toBe "I really like alot" - describe "snippet body parser", -> it "breaks a snippet body into lines, with each line containing tab stops at the appropriate position", -> bodyTree = snippets.getBodyParser().parse """ diff --git a/src/packages/spell-check/lib/misspelling-view.coffee b/src/packages/spell-check/lib/misspelling-view.coffee index ba57e4164..0940ce0f7 100644 --- a/src/packages/spell-check/lib/misspelling-view.coffee +++ b/src/packages/spell-check/lib/misspelling-view.coffee @@ -1,6 +1,7 @@ {View} = require 'space-pen' Range = require 'range' CorrectionsView = require './corrections-view' +SpellChecker = require 'spellchecker' module.exports = class MisspellingView extends View @@ -30,7 +31,7 @@ class MisspellingView extends View screenRange = @getScreenRange() misspelling = @editor.getTextInRange(@editor.bufferRangeForScreenRange(screenRange)) - corrections = $native.getCorrectionsForMisspelling(misspelling) + corrections = SpellChecker.getCorrectionsForMisspelling(misspelling) @correctionsView?.remove() @correctionsView = new CorrectionsView(@editor, corrections, screenRange) diff --git a/src/packages/spell-check/lib/spell-check-handler.coffee b/src/packages/spell-check/lib/spell-check-handler.coffee index 8040f4991..0b21f73ab 100644 --- a/src/packages/spell-check/lib/spell-check-handler.coffee +++ b/src/packages/spell-check/lib/spell-check-handler.coffee @@ -1,3 +1,5 @@ +SpellChecker = require 'spellchecker' + module.exports = findMisspellings: (text) -> wordRegex = /(?:^|[\s\[\]])([a-zA-Z']+)(?=[\s\.\[\]]|$)/g @@ -6,7 +8,7 @@ module.exports = for line in text.split('\n') while matches = wordRegex.exec(line) word = matches[1] - continue unless $native.isMisspelled(word) + continue unless SpellChecker.isMisspelled(word) startColumn = matches.index + matches[0].length - word.length endColumn = startColumn + word.length misspellings.push([[row, startColumn], [row, endColumn]]) diff --git a/src/packages/spell-check/lib/spell-check.coffee b/src/packages/spell-check/lib/spell-check.coffee index 2465b22df..9256e6c3c 100644 --- a/src/packages/spell-check/lib/spell-check.coffee +++ b/src/packages/spell-check/lib/spell-check.coffee @@ -9,10 +9,10 @@ module.exports = ] activate: -> - if syntax.grammars.length > 1 - @subscribeToEditors() - else - syntax.on 'grammars-loaded', => @subscribeToEditors() + syntax.on 'grammars-loaded.spell-check', => @subscribeToEditors() + + deactivate: -> + syntax.off '.spell-check' subscribeToEditors: -> rootView.eachEditor (editor) -> diff --git a/src/packages/spell-check/spec/spell-check-spec.coffee b/src/packages/spell-check/spec/spell-check-spec.coffee index 0756dbdeb..5ac927d96 100644 --- a/src/packages/spell-check/spec/spell-check-spec.coffee +++ b/src/packages/spell-check/spec/spell-check-spec.coffee @@ -4,10 +4,13 @@ describe "Spell check", -> [editor] = [] beforeEach -> + atom.activatePackage('text.tmbundle', sync: true) + atom.activatePackage('javascript.tmbundle', sync: true) window.rootView = new RootView rootView.open('sample.js') config.set('spell-check.grammars', []) - window.loadPackage('spell-check', activateImmediately: true) + atom.activatePackage('spell-check', immediate: true) + syntax.trigger 'grammars-loaded' rootView.attachToDom() editor = rootView.getActiveView() diff --git a/src/packages/status-bar/lib/status-bar-view.coffee b/src/packages/status-bar/lib/status-bar-view.coffee index f58d4dba0..ecae8af28 100644 --- a/src/packages/status-bar/lib/status-bar-view.coffee +++ b/src/packages/status-bar/lib/status-bar-view.coffee @@ -9,7 +9,7 @@ class StatusBarView extends View @appendToEditorPane(rootView, editor) if editor.attached @appendToEditorPane: (rootView, editor) -> - if pane = editor.pane() + if pane = editor.getPane() pane.append(new StatusBarView(rootView, editor)) @content: -> @@ -34,7 +34,7 @@ class StatusBarView extends View @updateCursorPositionText() @subscribe @editor, 'cursor:moved', => @updateCursorPositionText() - @subscribe @grammarName, 'click', => @editor.trigger 'editor:select-grammar' + @subscribe @grammarName, 'click', => @editor.trigger 'grammar-selector:show' @subscribe @editor, 'editor:grammar-changed', => @updateGrammarText() if git? @subscribe git, 'status-changed', (path, status) => @@ -58,7 +58,11 @@ class StatusBarView extends View @updateStatusText() updateGrammarText: -> - @grammarName.text(@editor.getGrammar().name) + grammar = @editor.getGrammar() + if grammar is syntax.nullGrammar + @grammarName.text('').hide() + else + @grammarName.text(grammar.name).show() updateBufferHasModifiedText: (isModified)-> if isModified @@ -110,6 +114,9 @@ class StatusBarView extends View else if git.isStatusNew(status) @gitStatusIcon.addClass('new-status-icon') @gitStatusIcon.text("+#{@buffer.getLineCount()}") + else if git.isPathIgnored(path) + @gitStatusIcon.addClass('ignored-status-icon') + @gitStatusIcon.text('') updatePathText: -> if path = @editor.getPath() diff --git a/src/packages/status-bar/spec/status-bar-spec.coffee b/src/packages/status-bar/spec/status-bar-spec.coffee index f7a88cf4d..497a4143d 100644 --- a/src/packages/status-bar/spec/status-bar-spec.coffee +++ b/src/packages/status-bar/spec/status-bar-spec.coffee @@ -2,7 +2,7 @@ $ = require 'jquery' _ = require 'underscore' RootView = require 'root-view' StatusBar = require 'status-bar/lib/status-bar-view' -fs = require 'fs' +fs = require 'fs-utils' describe "StatusBar", -> [editor, statusBar, buffer] = [] @@ -32,7 +32,7 @@ describe "StatusBar", -> describe "when associated with an unsaved buffer", -> it "displays 'untitled' instead of the buffer's path, but still displays the buffer position", -> - rootView.deactivate() + rootView.remove() window.rootView = new RootView rootView.open() rootView.simulateDomAttachment() @@ -112,7 +112,7 @@ describe "StatusBar", -> it "displays the current branch for files in repositories", -> path = require.resolve('fixtures/git/master.git/HEAD') - project.setPath(require.resolve('fixtures/git/master.git')) + project.setPath(fs.resolveOnLoadPath('fixtures/git/master.git')) rootView.open(path) expect(statusBar.branchArea).toBeVisible() expect(statusBar.branchLabel.text()).toBe 'master' @@ -124,12 +124,14 @@ describe "StatusBar", -> expect(statusBar.branchLabel.text()).toBe '' describe "git status label", -> - [repo, path, originalPathText, newPath] = [] + [repo, path, originalPathText, newPath, ignoredPath] = [] beforeEach -> path = require.resolve('fixtures/git/working-dir/file.txt') - newPath = fs.join(require.resolve('fixtures/git/working-dir'), 'new.txt') + newPath = fs.join(fs.resolveOnLoadPath('fixtures/git/working-dir'), 'new.txt') fs.write(newPath, "I'm new here") + ignoredPath = fs.join(fs.resolveOnLoadPath('fixtures/git/working-dir'), 'ignored.txt') + fs.write(ignoredPath, 'ignored.txt') git.getPathStatus(path) git.getPathStatus(newPath) originalPathText = fs.read(path) @@ -138,6 +140,7 @@ describe "StatusBar", -> afterEach -> fs.write(path, originalPathText) fs.remove(newPath) if fs.exists(newPath) + fs.remove(ignoredPath) if fs.exists(ignoredPath) it "displays the modified icon for a changed file", -> fs.write(path, "i've changed for the worse") @@ -153,6 +156,10 @@ describe "StatusBar", -> rootView.open(newPath) expect(statusBar.gitStatusIcon).toHaveClass('new-status-icon') + it "displays the ignored icon for an ignored file", -> + rootView.open(ignoredPath) + expect(statusBar.gitStatusIcon).toHaveClass('ignored-status-icon') + it "updates when a status-changed event occurs", -> fs.write(path, "i've changed for the worse") git.getPathStatus(path) @@ -173,19 +180,33 @@ describe "StatusBar", -> expect(statusBar.gitStatusIcon).toHaveText('+1') describe "grammar label", -> + beforeEach -> + atom.activatePackage('text.tmbundle', sync: true) + atom.activatePackage('javascript.tmbundle', sync: true) + syntax.trigger 'grammars-loaded' + it "displays the name of the current grammar", -> expect(statusBar.find('.grammar-name').text()).toBe 'JavaScript' + it "hides the label when the current grammar is the null grammar", -> + rootView.attachToDom() + editor.activeEditSession.languageMode.grammar = syntax.nullGrammar + editor.activeEditSession.trigger 'grammar-changed' + expect(statusBar.find('.grammar-name')).toBeHidden() + expect(statusBar.find('.grammar-name').text()).toBe '' + editor.reloadGrammar() + expect(statusBar.find('.grammar-name')).toBeVisible() + expect(statusBar.find('.grammar-name').text()).toBe 'JavaScript' + describe "when the editor's grammar changes", -> it "displays the new grammar of the editor", -> - textGrammar = _.find syntax.grammars, (grammar) -> grammar.name is 'Plain Text' - project.addGrammarOverrideForPath(editor.getPath(), textGrammar) + syntax.setGrammarOverrideForPath(editor.getPath(), 'text.plain') editor.reloadGrammar() - expect(statusBar.find('.grammar-name').text()).toBe textGrammar.name + expect(statusBar.find('.grammar-name').text()).toBe 'Plain Text' describe "when clicked", -> - it "toggles the editor:select-grammar event", -> + it "toggles the grammar-selector:show event", -> eventHandler = jasmine.createSpy('eventHandler') - editor.on 'editor:select-grammar', eventHandler + editor.on 'grammar-selector:show', eventHandler statusBar.find('.grammar-name').click() expect(eventHandler).toHaveBeenCalled() diff --git a/static/status-bar.less b/src/packages/status-bar/stylesheets/status-bar.less similarity index 93% rename from static/status-bar.less rename to src/packages/status-bar/stylesheets/status-bar.less index f30dd48c8..8ec139f34 100644 --- a/static/status-bar.less +++ b/src/packages/status-bar/stylesheets/status-bar.less @@ -57,6 +57,11 @@ content: "\f26b"; } +.status-bar .ignored-status-icon:before { + content: "\f099"; + margin-right: 0px; +} + .status-bar .commits-behind-label:before { margin-top: -3px; margin-left: 3px; diff --git a/src/packages/strip-trailing-whitespace/spec/strip-trailing-whitespace-spec.coffee b/src/packages/strip-trailing-whitespace/spec/strip-trailing-whitespace-spec.coffee index 17277b059..e41d2d3ab 100644 --- a/src/packages/strip-trailing-whitespace/spec/strip-trailing-whitespace-spec.coffee +++ b/src/packages/strip-trailing-whitespace/spec/strip-trailing-whitespace-spec.coffee @@ -1,5 +1,5 @@ RootView = require 'root-view' -fs = require 'fs' +fs = require 'fs-utils' describe "StripTrailingWhitespace", -> [editor, path] = [] @@ -10,7 +10,7 @@ describe "StripTrailingWhitespace", -> window.rootView = new RootView rootView.open(path) - window.loadPackage('strip-trailing-whitespace') + atom.activatePackage('strip-trailing-whitespace') rootView.focus() editor = rootView.getActiveView() diff --git a/src/packages/symbols-view/lib/load-tags-handler.coffee b/src/packages/symbols-view/lib/load-tags-handler.coffee new file mode 100644 index 000000000..860d037f5 --- /dev/null +++ b/src/packages/symbols-view/lib/load-tags-handler.coffee @@ -0,0 +1,17 @@ +ctags = require 'ctags' +fs = require 'fs-utils' + +module.exports = + getTagsFile: (path) -> + tagsFile = fs.join(path, "tags") + return tagsFile if fs.isFile(tagsFile) + + tagsFile = fs.join(path, "TAGS") + return tagsFile if fs.isFile(tagsFile) + + loadTags: (path) -> + tagsFile = @getTagsFile(path) + if tagsFile + callTaskMethod("tagsLoaded", ctags.getTags(tagsFile)) + else + callTaskMethod("tagsLoaded", []) diff --git a/src/packages/symbols-view/lib/load-tags-task.coffee b/src/packages/symbols-view/lib/load-tags-task.coffee new file mode 100644 index 000000000..99d8316d5 --- /dev/null +++ b/src/packages/symbols-view/lib/load-tags-task.coffee @@ -0,0 +1,13 @@ +Task = require 'task' + +module.exports = +class LoadTagsTask extends Task + constructor: (@callback) -> + super('symbols-view/lib/load-tags-handler') + + started: -> + @callWorkerMethod('loadTags', project.getPath()) + + tagsLoaded: (tags) -> + @done() + @callback(tags) diff --git a/src/packages/symbols-view/lib/symbols-view.coffee b/src/packages/symbols-view/lib/symbols-view.coffee index 10f347b66..816be9739 100644 --- a/src/packages/symbols-view/lib/symbols-view.coffee +++ b/src/packages/symbols-view/lib/symbols-view.coffee @@ -3,7 +3,7 @@ SelectList = require 'select-list' TagGenerator = require './tag-generator' TagReader = require './tag-reader' Point = require 'point' -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' module.exports = @@ -41,12 +41,10 @@ class SymbolsView extends SelectList @attach() populateFileSymbols: -> - tags = [] - callback = (tag) -> tags.push tag path = rootView.getActiveView().getPath() @list.empty() @setLoading("Generating symbols...") - new TagGenerator(path, callback).generate().done => + new TagGenerator(path).generate().done (tags) => if tags.length > 0 @miniEditor.show() @maxItem = Infinity diff --git a/src/packages/symbols-view/lib/tag-generator.coffee b/src/packages/symbols-view/lib/tag-generator.coffee index 7517d4dea..5960ed6a2 100644 --- a/src/packages/symbols-view/lib/tag-generator.coffee +++ b/src/packages/symbols-view/lib/tag-generator.coffee @@ -1,10 +1,11 @@ Point = require 'point' -ChildProcess = require 'child-process' +$ = require 'jquery' +BufferedProcess = require 'buffered-process' +fs = require 'fs-utils' module.exports = class TagGenerator - - constructor: (@path, @callback) -> + constructor: (@path) -> parseTagLine: (line) -> sections = line.split('\t') @@ -15,12 +16,15 @@ class TagGenerator null generate: -> - options = - bufferLines: true - stdout: (data) => - lines = data.split('\n') - for line in lines - tag = @parseTagLine(line) - @callback(tag) if tag - command = "#{require.resolve('ctags')} --fields=+KS -nf - #{@path}" - ChildProcess.exec(command, options) + deferred = $.Deferred() + tags = [] + command = fs.resolveOnLoadPath('ctags') + args = ['--fields=+KS', '-nf', '-', @path] + stdout = (lines) => + for line in lines.split('\n') + tag = @parseTagLine(line) + tags.push(tag) if tag + exit = -> + deferred.resolve(tags) + new BufferedProcess({command, args, stdout, exit}) + deferred diff --git a/src/packages/symbols-view/lib/tag-reader.coffee b/src/packages/symbols-view/lib/tag-reader.coffee index 86c96a892..dd7f069a7 100644 --- a/src/packages/symbols-view/lib/tag-reader.coffee +++ b/src/packages/symbols-view/lib/tag-reader.coffee @@ -1,5 +1,7 @@ -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' +LoadTagsTask = require './load-tags-task' +ctags = require 'ctags' module.exports = @@ -14,14 +16,11 @@ find: (editor) -> tagsFile = @getTagsFile(project) return [] unless tagsFile - $tags.find(tagsFile, word) or [] + ctags.findTags(tagsFile, word) getAllTags: (project, callback) -> deferred = $.Deferred() - tagsFile = @getTagsFile(project) - if tagsFile - $tags.getAllTagsAsync tagsFile, (tags) => - deferred.resolve(tags) - else - deferred.resolve([]) + callback = (tags=[]) => + deferred.resolve(tags) + new LoadTagsTask(callback).start() deferred.promise() diff --git a/src/packages/symbols-view/spec/symbols-view-spec.coffee b/src/packages/symbols-view/spec/symbols-view-spec.coffee index 30d9f69be..7401a4448 100644 --- a/src/packages/symbols-view/spec/symbols-view-spec.coffee +++ b/src/packages/symbols-view/spec/symbols-view-spec.coffee @@ -1,14 +1,14 @@ RootView = require 'root-view' SymbolsView = require 'symbols-view/lib/symbols-view' TagGenerator = require 'symbols-view/lib/tag-generator' -fs = require 'fs' +fs = require 'fs-utils' describe "SymbolsView", -> [symbolsView, setArraySpy] = [] beforeEach -> window.rootView = new RootView - window.loadPackage("symbols-view") + atom.activatePackage("symbols-view") rootView.attachToDom() setArraySpy = spyOn(SymbolsView.prototype, 'setArray').andCallThrough() @@ -83,13 +83,12 @@ describe "SymbolsView", -> it "moves the cursor to the selected function", -> tags = [] + waitsForPromise -> - tags = [] path = require.resolve('fixtures/sample.js') - callback = (tag) -> - tags.push tag - generator = new TagGenerator(path, callback) - generator.generate() + generator = new TagGenerator(path) + generator.generate().done (generatedTags) -> + tags = generatedTags runs -> rootView.open('sample.js') @@ -108,10 +107,9 @@ describe "SymbolsView", -> waitsForPromise -> path = require.resolve('fixtures/sample.js') - callback = (tag) -> - tags.push tag - generator = new TagGenerator(path, callback) - generator.generate() + generator = new TagGenerator(path) + generator.generate().done (generatedTags) -> + tags = generatedTags runs -> expect(tags.length).toBe 2 @@ -125,10 +123,9 @@ describe "SymbolsView", -> waitsForPromise -> path = require.resolve('fixtures/sample.txt') - callback = (tag) -> - tags.push tag - generator = new TagGenerator(path, callback) - generator.generate() + generator = new TagGenerator(path) + generator.generate().done (generatedTags) -> + tags = generatedTags runs -> expect(tags.length).toBe 0 diff --git a/src/packages/tabs/lib/tab-bar-view.coffee b/src/packages/tabs/lib/tab-bar-view.coffee index fbbab1330..68f41df86 100644 --- a/src/packages/tabs/lib/tab-bar-view.coffee +++ b/src/packages/tabs/lib/tab-bar-view.coffee @@ -47,9 +47,11 @@ class TabBarView extends SortableList tab.insertBefore(followingTab) else @append(tab) + tab.updateTitle() removeTabForItem: (item) -> @tabForItem(item).remove() + tab.updateTitle() for tab in @getTabs() getTabs: -> @children('.tab').toArray().map (elt) -> $(elt).view() diff --git a/src/packages/tabs/lib/tab-view.coffee b/src/packages/tabs/lib/tab-view.coffee index 9bfee397e..9e9594ef1 100644 --- a/src/packages/tabs/lib/tab-view.coffee +++ b/src/packages/tabs/lib/tab-view.coffee @@ -1,6 +1,6 @@ $ = require 'jquery' {View} = require 'space-pen' -fs = require 'fs' +fs = require 'fs-utils' module.exports = class TabView extends View diff --git a/src/packages/tabs/spec/tabs-spec.coffee b/src/packages/tabs/spec/tabs-spec.coffee index d8d32e390..820f3f9eb 100644 --- a/src/packages/tabs/spec/tabs-spec.coffee +++ b/src/packages/tabs/spec/tabs-spec.coffee @@ -4,14 +4,14 @@ RootView = require 'root-view' Pane = require 'pane' PaneContainer = require 'pane-container' TabBarView = require 'tabs/lib/tab-bar-view' -fs = require 'fs' +fs = require 'fs-utils' {View} = require 'space-pen' describe "Tabs package main", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - window.loadPackage("tabs") + atom.activatePackage("tabs") describe ".activate()", -> it "appends a tab bar all existing and new panes", -> @@ -88,6 +88,17 @@ describe "TabBarView", -> expect(tabBar.getTabs().length).toBe 2 expect(tabBar.find('.tab:contains(Item 2)')).not.toExist() + it "updates the titles of the remaining tabs", -> + expect(tabBar.tabForItem(item2)).toHaveText 'Item 2' + item2.longTitle = '2' + item2a = new TestView('Item 2') + item2a.longTitle = '2a' + pane.showItem(item2a) + expect(tabBar.tabForItem(item2)).toHaveText '2' + expect(tabBar.tabForItem(item2a)).toHaveText '2a' + pane.removeItem(item2a) + expect(tabBar.tabForItem(item2)).toHaveText 'Item 2' + describe "when a tab is clicked", -> it "shows the associated item on the pane and focuses the pane", -> spyOn(pane, 'focus') diff --git a/static/tabs.less b/src/packages/tabs/stylesheets/tabs.less similarity index 100% rename from static/tabs.less rename to src/packages/tabs/stylesheets/tabs.less diff --git a/src/packages/toml.tmbundle/Syntaxes/toml.cson b/src/packages/toml/grammars/toml.cson similarity index 100% rename from src/packages/toml.tmbundle/Syntaxes/toml.cson rename to src/packages/toml/grammars/toml.cson diff --git a/src/packages/toml.tmbundle/spec/toml-spec.coffee b/src/packages/toml/spec/toml-spec.coffee similarity index 95% rename from src/packages/toml.tmbundle/spec/toml-spec.coffee rename to src/packages/toml/spec/toml-spec.coffee index 576879912..656b99673 100644 --- a/src/packages/toml.tmbundle/spec/toml-spec.coffee +++ b/src/packages/toml/spec/toml-spec.coffee @@ -5,9 +5,9 @@ describe "TOML grammar", -> beforeEach -> spyOn(syntax, "addGrammar") - pack = new TextMatePackage(require.resolve("toml.tmbundle")) - pack.load() - grammar = pack.grammars[0] + atom.activatePackage("toml") + expect(syntax.addGrammar).toHaveBeenCalled() + grammar = syntax.addGrammar.argsForCall[0][0] it "parses the grammar", -> expect(grammar).toBeTruthy() diff --git a/src/packages/tree-view/lib/dialog.coffee b/src/packages/tree-view/lib/dialog.coffee index ddb71181a..858db818a 100644 --- a/src/packages/tree-view/lib/dialog.coffee +++ b/src/packages/tree-view/lib/dialog.coffee @@ -1,6 +1,6 @@ {View} = require 'space-pen' Editor = require 'editor' -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' module.exports = diff --git a/src/packages/tree-view/lib/file-view.coffee b/src/packages/tree-view/lib/file-view.coffee index f8d7f5115..5f264a15f 100644 --- a/src/packages/tree-view/lib/file-view.coffee +++ b/src/packages/tree-view/lib/file-view.coffee @@ -1,7 +1,7 @@ {View} = require 'space-pen' $ = require 'jquery' Git = require 'git' -fs = require 'fs' +fs = require 'fs-utils' module.exports = class FileView extends View @@ -14,19 +14,22 @@ class FileView extends View file: null initialize: ({@file, @project} = {}) -> - extension = fs.extension(@getPath()) - if fs.isReadmePath(@getPath()) - @fileName.addClass('readme-icon') - else if fs.isCompressedExtension(extension) - @fileName.addClass('compressed-icon') - else if fs.isImageExtension(extension) - @fileName.addClass('image-icon') - else if fs.isPdfExtension(extension) - @fileName.addClass('pdf-icon') - else if fs.isBinaryExtension(extension) - @fileName.addClass('binary-icon') + if @file.symlink + @fileName.addClass('symlink-icon') else - @fileName.addClass('text-icon') + extension = fs.extension(@getPath()) + if fs.isReadmePath(@getPath()) + @fileName.addClass('readme-icon') + else if fs.isCompressedExtension(extension) + @fileName.addClass('compressed-icon') + else if fs.isImageExtension(extension) + @fileName.addClass('image-icon') + else if fs.isPdfExtension(extension) + @fileName.addClass('pdf-icon') + else if fs.isBinaryExtension(extension) + @fileName.addClass('binary-icon') + else + @fileName.addClass('text-icon') if git? @subscribe git, 'status-changed', (path, status) => diff --git a/src/packages/tree-view/lib/tree-view.coffee b/src/packages/tree-view/lib/tree-view.coffee index 5a6ea480f..18475fa06 100644 --- a/src/packages/tree-view/lib/tree-view.coffee +++ b/src/packages/tree-view/lib/tree-view.coffee @@ -4,7 +4,7 @@ Directory = require 'directory' DirectoryView = require './directory-view' FileView = require './file-view' Dialog = require './dialog' -fs = require 'fs' +fs = require 'fs-utils' $ = require 'jquery' _ = require 'underscore' @@ -40,8 +40,8 @@ class TreeView extends ScrollView else @selectActiveFile() - rootView.on 'pane:active-item-changed pane:became-active', => @selectActiveFile() - project.on 'path-changed', => @updateRoot() + rootView.on 'pane:active-item-changed.tree-view pane:became-active.tree-view', => @selectActiveFile() + project.on 'path-changed.tree-view', => @updateRoot() @observeConfig 'core.hideGitIgnoredFiles', => @updateRoot() if @root @@ -67,6 +67,9 @@ class TreeView extends ScrollView deactivate: -> @root?.unwatchEntries() + rootView.off('.tree-view') + project.off('.tree-view') + @remove() toggle: -> if @hasFocus() @@ -222,6 +225,14 @@ class TreeView extends ScrollView iconClass: 'move' onConfirm: (newPath) => newPath = project.resolve(newPath) + if oldPath is newPath + dialog.close() + return + + if fs.exists(newPath) + dialog.showError("Error: #{newPath} already exists. Try a different path.") + return + directoryPath = fs.directory(newPath) try fs.makeTree(directoryPath) unless fs.exists(directoryPath) diff --git a/src/packages/tree-view/spec/tree-view-spec.coffee b/src/packages/tree-view/spec/tree-view-spec.coffee index d48f5577c..f5f01aace 100644 --- a/src/packages/tree-view/spec/tree-view-spec.coffee +++ b/src/packages/tree-view/spec/tree-view-spec.coffee @@ -4,7 +4,7 @@ _ = require 'underscore' TreeView = require 'tree-view/lib/tree-view' RootView = require 'root-view' Directory = require 'directory' -fs = require 'fs' +fs = require 'fs-utils' describe "TreeView", -> [treeView, sampleJs, sampleTxt] = [] @@ -13,7 +13,7 @@ describe "TreeView", -> project.setPath(project.resolve('tree-view')) window.rootView = new RootView - window.loadPackage("tree-view") + atom.activatePackage("tree-view") rootView.trigger 'tree-view:toggle' treeView = rootView.find(".tree-view").view() treeView.root = treeView.find('ol > li:first').view() @@ -47,10 +47,8 @@ describe "TreeView", -> describe "when the project has no path", -> beforeEach -> project.setPath(undefined) - rootView.deactivate() - window.rootView = new RootView() - rootView.open() - treeView = window.loadPackage("tree-view").mainModule.createView() + atom.deactivatePackage("tree-view") + treeView = atom.activatePackage("tree-view").mainModule.createView() it "does not attach to the root view or create a root node when initialized", -> expect(treeView.hasParent()).toBeFalsy() @@ -66,23 +64,24 @@ describe "TreeView", -> describe "when the project is assigned a path because a new buffer is saved", -> it "creates a root directory view but does not attach to the root view", -> + rootView.open() rootView.getActivePaneItem().saveAs("/tmp/test.txt") expect(treeView.hasParent()).toBeFalsy() - expect(treeView.root.getPath()).toBe require.resolve('/tmp') + expect(treeView.root.getPath()).toBe '/tmp' expect(treeView.root.parent()).toMatchSelector(".tree-view") describe "when the root view is opened to a file path", -> it "does not attach to the root view but does create a root node when initialized", -> - rootView.deactivate() - window.rootView = new RootView + atom.deactivatePackage("tree-view") + atom.packageStates = {} rootView.open('tree-view.js') - treeView = window.loadPackage("tree-view").mainModule.createView() + treeView = atom.activatePackage("tree-view").mainModule.createView() expect(treeView.hasParent()).toBeFalsy() expect(treeView.root).toExist() describe "when the root view is opened to a directory", -> it "attaches to the root view", -> - treeView = window.loadPackage("tree-view").mainModule.createView() + treeView = atom.activatePackage("tree-view").mainModule.createView() expect(treeView.hasParent()).toBeTruthy() expect(treeView.root).toExist() @@ -91,10 +90,8 @@ describe "TreeView", -> treeView.find('.directory:contains(dir1)').click() sampleJs.click() - rootViewState = rootView.serialize() - rootView.deactivate() - window.rootView = RootView.deserialize(rootViewState) - window.loadPackage("tree-view") + atom.deactivatePackage("tree-view") + atom.activatePackage("tree-view") treeView = rootView.find(".tree-view").view() expect(treeView).toExist() @@ -105,13 +102,8 @@ describe "TreeView", -> rootView.attachToDom() treeView.focus() expect(treeView.find(".tree-view")).toMatchSelector ':focus' - - rootViewState = rootView.serialize() - rootView.deactivate() - window.rootView = RootView.deserialize(rootViewState) - - rootView.attachToDom() - window.loadPackage("tree-view") + atom.deactivatePackage("tree-view") + atom.activatePackage("tree-view") treeView = rootView.find(".tree-view").view() expect(treeView.find(".tree-view")).toMatchSelector ':focus' @@ -267,20 +259,20 @@ describe "TreeView", -> sampleJs.trigger clickEvent(originalEvent: { detail: 1 }) expect(sampleJs).toHaveClass 'selected' - expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js') + expect(rootView.getActiveView().getPath()).toBe fs.resolveOnLoadPath('fixtures/tree-view/tree-view.js') expect(rootView.getActiveView().isFocused).toBeFalsy() sampleTxt.trigger clickEvent(originalEvent: { detail: 1 }) expect(sampleTxt).toHaveClass 'selected' expect(treeView.find('.selected').length).toBe 1 - expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.txt') + expect(rootView.getActiveView().getPath()).toBe fs.resolveOnLoadPath('fixtures/tree-view/tree-view.txt') expect(rootView.getActiveView().isFocused).toBeFalsy() describe "when a file is double-clicked", -> it "selects the file and opens it in the active editor on the first click, then changes focus to the active editor on the second", -> sampleJs.trigger clickEvent(originalEvent: { detail: 1 }) expect(sampleJs).toHaveClass 'selected' - expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js') + expect(rootView.getActiveView().getPath()).toBe fs.resolveOnLoadPath('fixtures/tree-view/tree-view.js') expect(rootView.getActiveView().isFocused).toBeFalsy() sampleJs.trigger clickEvent(originalEvent: { detail: 2 }) @@ -576,7 +568,7 @@ describe "TreeView", -> it "opens the file in the editor and focuses it", -> treeView.root.find('.file:contains(tree-view.js)').click() treeView.root.trigger 'tree-view:open-selected-entry' - expect(rootView.getActiveView().getPath()).toBe require.resolve('fixtures/tree-view/tree-view.js') + expect(rootView.getActiveView().getPath()).toBe fs.resolveOnLoadPath('fixtures/tree-view/tree-view.js') expect(rootView.getActiveView().isFocused).toBeTruthy() describe "when a directory is selected", -> @@ -599,9 +591,9 @@ describe "TreeView", -> [dirView, fileView, rootDirPath, dirPath, filePath] = [] beforeEach -> - rootView.deactivate() + atom.deactivatePackage('tree-view') - rootDirPath = "/tmp/atom-tests" + rootDirPath = fs.join(fs.absolute("/tmp"), "atom-tests") fs.remove(rootDirPath) if fs.exists(rootDirPath) dirPath = fs.join(rootDirPath, "test-dir") @@ -611,8 +603,8 @@ describe "TreeView", -> fs.write(filePath, "doesn't matter") project.setPath(rootDirPath) - window.rootView = new RootView(rootDirPath) - window.loadPackage('tree-view') + + atom.activatePackage('tree-view') rootView.trigger 'tree-view:toggle' treeView = rootView.find(".tree-view").view() dirView = treeView.root.entries.find('.directory:contains(test-dir)').view() @@ -883,7 +875,7 @@ describe "TreeView", -> temporaryFilePath = null beforeEach -> - temporaryFilePath = fs.join(require.resolve('fixtures/tree-view'), 'temporary') + temporaryFilePath = fs.join(fs.resolveOnLoadPath('fixtures/tree-view'), 'temporary') if fs.exists(temporaryFilePath) fs.remove(temporaryFilePath) waits(20) @@ -915,7 +907,7 @@ describe "TreeView", -> [ignoreFile] = [] beforeEach -> - ignoreFile = fs.join(require.resolve('fixtures/tree-view'), '.gitignore') + ignoreFile = fs.join(fs.resolveOnLoadPath('fixtures/tree-view'), '.gitignore') fs.write(ignoreFile, 'tree-view.js') config.set "core.hideGitIgnoredFiles", false @@ -938,15 +930,15 @@ describe "TreeView", -> beforeEach -> config.set "core.hideGitIgnoredFiles", false - ignoreFile = fs.join(require.resolve('fixtures/tree-view'), '.gitignore') + ignoreFile = fs.join(fs.resolveOnLoadPath('fixtures/tree-view'), '.gitignore') fs.write(ignoreFile, 'tree-view.js') git.getPathStatus(ignoreFile) - newFile = fs.join(require.resolve('fixtures/tree-view/dir2'), 'new2') + newFile = fs.join(fs.resolveOnLoadPath('fixtures/tree-view/dir2'), 'new2') fs.write(newFile, '') git.getPathStatus(newFile) - modifiedFile = fs.join(require.resolve('fixtures/tree-view/dir1'), 'file1') + modifiedFile = fs.join(fs.resolveOnLoadPath('fixtures/tree-view/dir1'), 'file1') originalFileContent = fs.read(modifiedFile) fs.write modifiedFile, 'ch ch changes' git.getPathStatus(modifiedFile) diff --git a/src/packages/tree-view/stylesheets/tree-view.less b/src/packages/tree-view/stylesheets/tree-view.less index 33c9db860..d082dead4 100644 --- a/src/packages/tree-view/stylesheets/tree-view.less +++ b/src/packages/tree-view/stylesheets/tree-view.less @@ -1,3 +1,144 @@ +.tree-view .entries { + margin-left: 12px; +} + +.tree-view .entries .file .name { + margin-left: 20px; +} + +.tree-view .file .name, +.tree-view .directory .header { + padding-top: 4px; + padding-bottom: 4px; + padding-right: 10px; +} + +.tree-view .directory .header { + padding-left: 5px; +} + +.tree-view-dialog { + padding: 5px; +} + +.tree-view-dialog .prompt { + padding-bottom: 3px; + font-size: 12px; + line-height: 16px; +} + +.tree-view-dialog .prompt span { + position: relative; + top: -1px; +} + +.tree-view-dialog .prompt:before { + font-family: 'Octicons Regular'; + font-size: 16px; + width: 16px; + height: 16px; + margin-right: 3px; + -webkit-font-smoothing: antialiased; +} + +.tree-view-dialog .prompt.add-file:before { + content: "\f086"; +} + +.tree-view-dialog .prompt.add-directory:before { + content: "\f095"; +} + +.tree-view-dialog .prompt.move:before { + content: "\f03e"; +} + +.tree-view .directory .header .name, +.tree-view .file .name { + position: relative; + padding-left: 21px; +} + +.tree-view .directory .header .name:before, +.tree-view .file .name:before { + font-family: 'Octicons Regular'; + font-size: 16px; + width: 16px; + height: 16px; + margin-right: 5px; + -webkit-font-smoothing: antialiased; + position: absolute; + left: 0; +} + +.tree-view .disclosure-arrow:before { + font-family: 'Octicons Regular'; + font-size: 12px; + width: 12px; + height: 12px; + line-height: 16px; + margin-right: 3px; + -webkit-font-smoothing: antialiased; +} + +.tree-view .directory .header .directory-icon:before { + content: "\f016"; + top: -5px; +} + +.tree-view .directory .header .repository-icon:before { + content: "\f001"; + top: -4px; +} + +.tree-view .directory .header .submodule-icon:before { + content: "\f017"; + top: -5px; +} + +.tree-view .file .text-icon:before { + content: "\f011"; + top: -2px; +} + +.tree-view .file .image-icon:before { + content: "\f012"; + top: -2px; +} + +.tree-view .file .compressed-icon:before { + content: "\f013"; + top: -2px; +} + +.tree-view .file .pdf-icon:before { + content: "\f014"; + top: -2px; +} + +.tree-view .file .readme-icon:before { + content: "\f007"; + top: -2px; +} + +.tree-view .file .binary-icon:before { + content: "\f094"; + top: -2px; +} + +.tree-view .file .symlink-icon:before { + content: "\f09b"; + top: -2px; +} + +.tree-view .directory > .header .disclosure-arrow:before { + content: "\f05a"; +} + +.tree-view .directory.expanded > .header .disclosure-arrow:before { + content: "\f05b"; +} + .tree-view-wrapper { position: relative; height: 100%; diff --git a/src/packages/wrap-guide/spec/wrap-guide-spec.coffee b/src/packages/wrap-guide/spec/wrap-guide-spec.coffee index ff14f7c27..cd0761881 100644 --- a/src/packages/wrap-guide/spec/wrap-guide-spec.coffee +++ b/src/packages/wrap-guide/spec/wrap-guide-spec.coffee @@ -6,7 +6,7 @@ describe "WrapGuide", -> beforeEach -> window.rootView = new RootView rootView.open('sample.js') - window.loadPackage('wrap-guide') + atom.activatePackage('wrap-guide') rootView.attachToDom() editor = rootView.getActiveView() wrapGuide = rootView.find('.wrap-guide').view() diff --git a/src/stdlib/buffered-process.coffee b/src/stdlib/buffered-process.coffee new file mode 100644 index 000000000..04fcf3ce9 --- /dev/null +++ b/src/stdlib/buffered-process.coffee @@ -0,0 +1,48 @@ +ChildProcess = require 'child_process' + +module.exports = +class BufferedProcess + constructor: ({command, args, options, stdout, stderr, exit}={}) -> + process = ChildProcess.spawn(command, args, options) + + stdoutClosed = true + stderrClosed = true + processExited = true + exitCode = 0 + triggerExitCallback = -> + if stdoutClosed and stderrClosed and processExited + exit?(exitCode) + + if stdout + stdoutClosed = false + @bufferStream process.stdout, stdout, -> + stdoutClosed = true + triggerExitCallback() + + if stderr + stderrClosed = false + @bufferStream process.stderr, stderr, -> + stderrClosed = true + triggerExitCallback() + + if exit + processExited = false + process.on 'exit', (code) -> + exitCode = code + processExited = true + triggerExitCallback() + + bufferStream: (stream, onLines, onDone) -> + stream.setEncoding('utf8') + buffered = '' + + stream.on 'data', (data) -> + buffered += data + lastNewlineIndex = buffered.lastIndexOf('\n') + if lastNewlineIndex isnt -1 + onLines(buffered.substring(0, lastNewlineIndex + 1)) + buffered = buffered.substring(lastNewlineIndex + 1) + + stream.on 'close', => + onLines(buffered) if buffered.length > 0 + onDone() diff --git a/src/stdlib/child-process.coffee b/src/stdlib/child-process.coffee deleted file mode 100644 index a9228c55c..000000000 --- a/src/stdlib/child-process.coffee +++ /dev/null @@ -1,37 +0,0 @@ -# node.js child-process -# http://nodejs.org/docs/v0.6.3/api/child_processes.html - -$ = require 'jquery' -_ = require 'underscore' - -module.exports = -class ChildProccess - @exec: (command, options={}) -> - deferred = $.Deferred() - - if options.bufferLines - options.stdout = @bufferLines(options.stdout) if options.stdout - options.stderr = @bufferLines(options.stderr) if options.stderr - - $native.exec command, options, (exitStatus, stdout, stderr) -> - options.stdout?(stdout) - options.stderr?(stderr) - try - if exitStatus != 0 - deferred.reject({command, exitStatus}) - else - deferred.resolve() - catch e - console.error "In ChildProccess termination callback: ", e.message - console.error e.stack - - deferred - - @bufferLines: (callback) -> - buffered = "" - (data) -> - buffered += data - lastNewlineIndex = buffered.lastIndexOf('\n') - if lastNewlineIndex >= 0 - callback(buffered.substring(0, lastNewlineIndex + 1)) - buffered = buffered.substring(lastNewlineIndex + 1) diff --git a/src/stdlib/cson.coffee b/src/stdlib/cson.coffee index 84832f35f..6d331483d 100644 --- a/src/stdlib/cson.coffee +++ b/src/stdlib/cson.coffee @@ -1,7 +1,37 @@ require 'underscore-extensions' _ = require 'underscore' +fs = require 'fs' +fsUtils = require 'fs-utils' module.exports = + isObjectPath: (path) -> + extension = fsUtils.extension(path) + extension is '.cson' or extension is '.json' + + readObject: (path) -> + @parseObject(path, fsUtils.read(path)) + + readObjectAsync: (path, done) -> + fs.readFile path, 'utf8', (err, contents) => + return done(err) if err? + try done(null, @parseObject(path, contents)) + catch err + done(err) + + parseObject: (path, contents) -> + if fsUtils.extension(path) is '.cson' + CoffeeScript = require 'coffee-script' + CoffeeScript.eval(contents, bare: true) + else + JSON.parse(contents) + + writeObject: (path, object) -> + if fsUtils.extension(path) is '.cson' + content = @stringify(object) + else + content = JSON.stringify(object, undefined, 2) + fsUtils.write(path, "#{content}\n") + stringifyIndent: (level=0) -> _.multiplyString(' ', Math.max(level, 0)) stringifyString: (string) -> diff --git a/src/stdlib/event.coffee b/src/stdlib/event.coffee deleted file mode 100644 index adf761d97..000000000 --- a/src/stdlib/event.coffee +++ /dev/null @@ -1,20 +0,0 @@ -_ = require 'underscore' - -module.exports = -class Event - events: {} - - on: (name, callback) -> - @events[name] ?= [] - @events[name].push callback - - off: (name, callback) -> - delete @events[name][_.indexOf callback] if @events[name] - - trigger: (name, data...) -> - if name.match /^app:/ - OSX.NSApp.triggerGlobalAtomEvent_data name, data - return - - _.each @events[name], (callback) => callback data... - null diff --git a/src/stdlib/fs-utils.coffee b/src/stdlib/fs-utils.coffee new file mode 100644 index 000000000..1acf41169 --- /dev/null +++ b/src/stdlib/fs-utils.coffee @@ -0,0 +1,322 @@ +# commonjs fs module +# http://ringojs.org/api/v0.8/fs/ + +_ = require 'underscore' +fs = require 'fs' +mkdirp = require 'mkdirp' +Module = require 'module' +async = require 'async' + +module.exports = + # Make the given path absolute by resolving it against the + # current working directory. + absolute: (path) -> + return null unless path? + + if path.indexOf('~/') is 0 + if process.platform is 'win32' + home = process.env.USERPROFILE + else + home = process.env.HOME + path = "#{home}#{path.substring(1)}" + try + fs.realpathSync(path) + catch e + path + + # Return the basename of the given path. That is the path with + # any leading directory components removed. If specified, also + # remove a trailing extension. + base: (path, ext) -> + base = path.replace(/\/$/, '').split("/").pop() + if ext then base.replace(RegExp("#{_.escapeRegExp(ext)}$"), '') else base + + # Returns the path of a file's containing directory, albeit the + # parent directory if the file is a directory. A terminal directory + # separator is ignored. + directory: (path) -> + parentPath = path.replace(new RegExp("/#{@base(_.escapeRegExp(path))}\/?$"), '') + return "" if path == parentPath + parentPath + + # Returns true if the file specified by path exists + exists: (path) -> + path? and fs.existsSync(path) + + # Returns the extension of a file. The extension of a file is the + # last dot (excluding any number of initial dots) followed by one or + # more non-dot characters. Returns an empty string if no valid + # extension exists. + extension: (path) -> + return '' unless typeof path is 'string' + match = @base(path).match(/\.[^\.]+$/) + if match + match[0] + else + "" + + join: (paths...) -> + return paths[0] if paths.length == 1 + [first, rest...] = paths + first.replace(/\/?$/, "/") + @join(rest...) + + # Returns true if the file specified by path exists and is a + # directory. + isDirectory: (path) -> + return false unless path?.length > 0 + try + fs.statSync(path).isDirectory() + catch e + false + + isDirectoryAsync: (path, done) -> + return done(false) unless path?.length > 0 + fs.exists path, (exists) -> + if exists + fs.stat path, (err, stat) -> + done(stat?.isDirectory() ? false) + else + done(false) + + # Returns true if the file specified by path exists and is a + # regular file. + isFile: (path) -> + return false unless path?.length > 0 + try + path? and fs.statSync(path).isFile() + catch e + false + + # Returns an array with all the names of files contained + # in the directory path. + list: (rootPath, extensions) -> + return unless @isDirectory(rootPath) + paths = fs.readdirSync(rootPath) + paths = @filterExtensions(paths, extensions) if extensions + paths = paths.map (path) => @join(rootPath, path) + paths + + listAsync: (rootPath, rest...) -> + extensions = rest.shift() if rest.length > 1 + done = rest.shift() + fs.readdir rootPath, (err, paths) => + return done(err) if err + paths = @filterExtensions(paths, extensions) if extensions + paths = paths.map (path) => @join(rootPath, path) + done(null, paths) + + filterExtensions: (paths, extensions) -> + extensions = extensions.map (ext) -> '.' + ext.replace(/^\./, '') + paths.filter (path) => _.include(extensions, @extension(path)) + + listTree: (rootPath) -> + paths = [] + onPath = (path) => + paths.push(path) + true + @traverseTreeSync(rootPath, onPath, onPath) + paths + + move: (source, target) -> + fs.renameSync(source, target) + + # Remove a file at the given path. Throws an error if path is not a + # file or a symbolic link to a file. + remove: (path) -> + if @isFile(path) + fs.unlinkSync(path) + else if @isDirectory(path) + removeDirectory = (path) => + for entry in fs.readdirSync(path) + entryPath = @join(path, entry) + stats = fs.statSync(entryPath) + if stats.isDirectory() + removeDirectory(entryPath) + else if stats.isFile() + fs.unlinkSync(entryPath) + fs.rmdirSync(path) + removeDirectory(path) + + # Open, read, and close a file, returning the file's contents. + read: (path) -> + String fs.readFileSync(path) + + # Returns an array of path components. If the path is absolute, the first + # component will be an indicator of the root of the file system; for file + # systems with drives (such as Windows), this is the drive identifier with a + # colon, like "c:"; on Unix, this is an empty string "". The intent is that + # calling "join.apply" with the result of "split" as arguments will + # reconstruct the path. + split: (path) -> + path.split("/") + + # Open, write, flush, and close a file, writing the given content. + write: (path, content) -> + mkdirp.sync(@directory(path)) + fs.writeFileSync(path, content) + + makeDirectory: (path) -> + fs.mkdirSync(path) + + # Creates the directory specified by "path" including any missing parent + # directories. + makeTree: (path) -> + return unless path + if not @exists(path) + @makeTree(@directory(path)) + @makeDirectory(path) + + traverseTreeSync: (rootPath, onFile, onDirectory) -> + return unless @isDirectory(rootPath) + + traverse = (rootPath, prefix, onFile, onDirectory) => + prefix = "#{prefix}/" if prefix + for file in fs.readdirSync(rootPath) + relativePath = "#{prefix}#{file}" + absolutePath = @join(rootPath, file) + stats = fs.statSync(absolutePath) + if stats.isDirectory() + traverse(absolutePath, relativePath, onFile, onDirectory) if onDirectory(absolutePath) + else if stats.isFile() + onFile(absolutePath) + + traverse(rootPath, '', onFile, onDirectory) + + traverseTree: (rootPath, onFile, onDirectory, onDone) -> + fs.readdir rootPath, (error, files) => + if error + onDone() + else + queue = async.queue (path, callback) => + fs.stat path, (error, stats) => + if error + callback(error) + else if stats.isFile() + onFile(path) + callback() + else if stats.isDirectory() + if onDirectory(path) + fs.readdir path, (error, files) => + if error + callback(error) + else + for file in files + queue.unshift(@join(path, file)) + callback() + else + callback() + queue.concurrency = 1 + queue.drain = onDone + queue.push(@join(rootPath, file)) for file in files + + md5ForPath: (path) -> + contents = fs.readFileSync(path) + require('crypto').createHash('md5').update(contents).digest('hex') + + resolve: (args...) -> + extensions = args.pop() if _.isArray(_.last(args)) + pathToResolve = args.pop() + loadPaths = args + + if pathToResolve[0] is '/' + if extensions and resolvedPath = @resolveExtension(pathToResolve, extensions) + return resolvedPath + else + return pathToResolve if @exists(pathToResolve) + + for loadPath in loadPaths + candidatePath = @join(loadPath, pathToResolve) + if extensions + if resolvedPath = @resolveExtension(candidatePath, extensions) + return resolvedPath + else + return @absolute(candidatePath) if @exists(candidatePath) + undefined + + resolveOnLoadPath: (args...) -> + loadPaths = Module.globalPaths.concat(module.paths) + @resolve(loadPaths..., args...) + + resolveExtension: (path, extensions) -> + for extension in extensions + if extension == "" + return @absolute(path) if @exists(path) + else + pathWithExtension = path + "." + extension.replace(/^\./, "") + return @absolute(pathWithExtension) if @exists(pathWithExtension) + undefined + + isCompressedExtension: (ext) -> + _.indexOf([ + '.gz' + '.jar' + '.tar' + '.zip' + ], ext, true) >= 0 + + isImageExtension: (ext) -> + _.indexOf([ + '.gif' + '.jpeg' + '.jpg' + '.png' + '.tiff' + ], ext, true) >= 0 + + isPdfExtension: (ext) -> + ext is '.pdf' + + isMarkdownExtension: (ext) -> + _.indexOf([ + '.markdown' + '.md' + '.mkd' + '.mkdown' + '.ron' + ], ext, true) >= 0 + + isBinaryExtension: (ext) -> + _.indexOf([ + '.DS_Store' + '.woff' + ], ext, true) >= 0 + + isReadmePath: (path) -> + extension = @extension(path) + base = @base(path, extension).toLowerCase() + base is 'readme' and (extension is '' or @isMarkdownExtension(extension)) + + readPlist: (path) -> + plist = require 'plist' + plist.parseStringSync(@read(path)) + + readPlistAsync: (path, done) -> + plist = require 'plist' + fs.readFile path, 'utf8', (err, contents) -> + return done(err) if err + try + done(null, plist.parseStringSync(contents)) + catch err + done(err) + + readObject: (path) -> + cson = require 'cson' + if cson.isObjectPath(path) + cson.readObject(path) + else + @readPlist(path) + + readObjectAsync: (path, done) -> + cson = require 'cson' + if cson.isObjectPath(path) + cson.readObjectAsync(path, done) + else + @readPlistAsync(path, done) + + watchPath: (path, callback) -> + path = @absolute(path) + watchCallback = (eventType, eventPath) => + path = @absolute(eventPath) if eventType is 'move' + callback(arguments...) + id = $native.watchPath(path, watchCallback) + unwatch: -> $native.unwatchPath(path, id) diff --git a/src/stdlib/fs.coffee b/src/stdlib/fs.coffee deleted file mode 100644 index 5d9ffe226..000000000 --- a/src/stdlib/fs.coffee +++ /dev/null @@ -1,220 +0,0 @@ -# commonjs fs module -# http://ringojs.org/api/v0.8/fs/ - -_ = require 'underscore' - -module.exports = - # Make the given path absolute by resolving it against the - # current working directory. - absolute: (path) -> - $native.absolute(path) - - # Return the basename of the given path. That is the path with - # any leading directory components removed. If specified, also - # remove a trailing extension. - base: (path, ext) -> - base = path.replace(/\/$/, '').split("/").pop() - if ext then base.replace(RegExp("#{_.escapeRegExp(ext)}$"), '') else base - - # Returns the path of a file's containing directory, albeit the - # parent directory if the file is a directory. A terminal directory - # separator is ignored. - directory: (path) -> - parentPath = path.replace(new RegExp("/#{@base(_.escapeRegExp(path))}\/?$"), '') - return "" if path == parentPath - parentPath - - # Returns true if the file specified by path exists - exists: (path) -> - return false unless path? - $native.exists(path) - - # Returns the extension of a file. The extension of a file is the - # last dot (excluding any number of initial dots) followed by one or - # more non-dot characters. Returns an empty string if no valid - # extension exists. - extension: (path) -> - return '' unless typeof path is 'string' - match = @base(path).match(/\.[^\.]+$/) - if match - match[0] - else - "" - - join: (paths...) -> - return paths[0] if paths.length == 1 - [first, rest...] = paths - first.replace(/\/?$/, "/") + @join(rest...) - - # Returns true if the file specified by path exists and is a - # directory. - isDirectory: (path) -> - $native.isDirectory path - - # Returns true if the file specified by path exists and is a - # regular file. - isFile: (path) -> - return false unless path? - $native.isFile(path) - - # Returns an array with all the names of files contained - # in the directory path. - list: (rootPath, extensions) -> - paths = [] - if extensions - onPath = (path) => - paths.push(path) if _.contains(extensions, @extension(path)) - false - else - onPath = (path) => - paths.push(path) - false - @traverseTree(rootPath, onPath, onPath) - paths - - listTree: (rootPath) -> - paths = [] - onPath = (path) => - paths.push(path) - true - @traverseTree(rootPath, onPath, onPath) - paths - - move: (source, target) -> - $native.move(source, target) - - # Remove a file at the given path. Throws an error if path is not a - # file or a symbolic link to a file. - remove: (path) -> - $native.remove path - - # Open, read, and close a file, returning the file's contents. - read: (path) -> - $native.read(path) - - # Returns an array of path components. If the path is absolute, the first - # component will be an indicator of the root of the file system; for file - # systems with drives (such as Windows), this is the drive identifier with a - # colon, like "c:"; on Unix, this is an empty string "". The intent is that - # calling "join.apply" with the result of "split" as arguments will - # reconstruct the path. - split: (path) -> - path.split("/") - - # Open, write, flush, and close a file, writing the given content. - write: (path, content) -> - $native.write(path, content) - - makeDirectory: (path) -> - $native.makeDirectory(path) - - # Creates the directory specified by "path" including any missing parent - # directories. - makeTree: (path) -> - return unless path - if not @exists(path) - @makeTree(@directory(path)) - @makeDirectory(path) - - getAllFilePathsAsync: (rootPath, callback) -> - $native.getAllFilePathsAsync(rootPath, callback) - - traverseTree: (rootPath, onFile, onDirectory) -> - $native.traverseTree(rootPath, onFile, onDirectory) - - lastModified: (path) -> - $native.lastModified(path) - - md5ForPath: (path) -> - $native.md5ForPath(path) - - resolve: (args...) -> - extensions = args.pop() if _.isArray(_.last(args)) - pathToResolve = args.pop() - loadPaths = args - - for loadPath in loadPaths - candidatePath = @join(loadPath, pathToResolve) - if extensions - if resolvedPath = @resolveExtension(candidatePath, extensions) - return resolvedPath - else - return candidatePath if @exists(candidatePath) - undefined - - resolveExtension: (path, extensions) -> - for extension in extensions - if extension == "" - return path if @exists(path) - else - pathWithExtension = path + "." + extension.replace(/^\./, "") - return pathWithExtension if @exists(pathWithExtension) - undefined - - isCompressedExtension: (ext) -> - _.indexOf([ - '.gz' - '.jar' - '.tar' - '.zip' - ], ext, true) >= 0 - - isImageExtension: (ext) -> - _.indexOf([ - '.gif' - '.jpeg' - '.jpg' - '.png' - '.tiff' - ], ext, true) >= 0 - - isPdfExtension: (ext) -> - ext is '.pdf' - - isMarkdownExtension: (ext) -> - _.indexOf([ - '.markdown' - '.md' - '.mkd' - '.mkdown' - '.ron' - ], ext, true) >= 0 - - isBinaryExtension: (ext) -> - _.indexOf([ - '.DS_Store' - '.woff' - ], ext, true) >= 0 - - isReadmePath: (path) -> - extension = @extension(path) - base = @base(path, extension).toLowerCase() - base is 'readme' and (extension is '' or @isMarkdownExtension(extension)) - - isObjectPath: (path) -> - extension = @extension(path) - extension is '.cson' or extension is '.json' - - readObject: (path) -> - contents = @read(path) - if @extension(path) is '.cson' - {CoffeeScript} = require 'coffee-script' - CoffeeScript.eval(contents, bare: true) - else - JSON.parse(contents) - - writeObject: (path, object) -> - if @extension(path) is '.cson' - CSON = require 'cson' - content = CSON.stringify(object) - else - content = JSON.stringify(object, undefined, 2) - @write(path, "#{content}\n") - - readPlist: (path) -> - plist = require 'plist' - object = null - plist.parseString @read(path), (e, data) -> - throw new Error(e) if e - object = data[0] - object diff --git a/src/stdlib/git-repository.coffee b/src/stdlib/git-repository.coffee deleted file mode 100644 index 4a1291e8b..000000000 --- a/src/stdlib/git-repository.coffee +++ /dev/null @@ -1,21 +0,0 @@ -module.exports = -class GitRepository - @open: (path) -> - unless repo = $git.getRepository(path) - throw new Error("No Git repository found searching path: #{path}") - repo.constructor = GitRepository - repo.__proto__ = GitRepository.prototype - repo - - getHead: $git.getHead - getPath: $git.getPath - getStatus: $git.getStatus - getStatuses: $git.getStatuses - isIgnored: $git.isIgnored - checkoutHead: $git.checkoutHead - getDiffStats: $git.getDiffStats - isSubmodule: $git.isSubmodule - refreshIndex: $git.refreshIndex - destroy: $git.destroy - getAheadBehindCounts: $git.getAheadBehindCounts - getLineDiffs: $git.getLineDiffs diff --git a/src/stdlib/jquery-extensions.coffee b/src/stdlib/jquery-extensions.coffee index fe403c2a9..7a62a988c 100644 --- a/src/stdlib/jquery-extensions.coffee +++ b/src/stdlib/jquery-extensions.coffee @@ -59,7 +59,9 @@ $.fn.trueHeight = -> $.fn.trueWidth = -> this[0].getBoundingClientRect().width -$.fn.document = (eventDescriptions) -> +$.fn.document = (eventName, docString) -> + eventDescriptions = {} + eventDescriptions[eventName] = docString @data('documentation', {}) unless @data('documentation') _.extend(@data('documentation'), eventDescriptions) @@ -75,16 +77,27 @@ $.fn.events = -> else events -$.fn.command = (args...) -> - eventName = args[0] - documentation = {} - documentation[eventName] = _.humanizeEventName(eventName) - @document(documentation) - @on(args...) +$.fn.command = (eventName, selector, options, handler) -> + if not options? + handler = selector + selector = null + else if not handler? + handler = options + options = null + + if selector? and typeof(selector) is 'object' + options = selector + selector = null + + @document(eventName, _.humanizeEventName(eventName, options?["doc"])) + @on(eventName, selector, options?['data'], handler) $.fn.iconSize = (size) -> @width(size).height(size).css('font-size', size) +$.fn.intValue = -> + parseInt(@text()) + $.Event.prototype.abortKeyBinding = -> $.Event.prototype.currentTargetView = -> $(this.currentTarget).view() $.Event.prototype.targetView = -> $(this.target).view() diff --git a/src/stdlib/onig-reg-exp.coffee b/src/stdlib/onig-reg-exp.coffee deleted file mode 100644 index db7fa4632..000000000 --- a/src/stdlib/onig-reg-exp.coffee +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = -class OnigRegExp - @create: (source) -> - regexp = $onigRegExp.buildOnigRegExp(source); - regexp.constructor = OnigRegExp - regexp.__proto__ = OnigRegExp.prototype - regexp.source = source - regexp - - search: $onigRegExp.search - test: $onigRegExp.test diff --git a/src/stdlib/onig-scanner.coffee b/src/stdlib/onig-scanner.coffee deleted file mode 100644 index 80c457c2f..000000000 --- a/src/stdlib/onig-scanner.coffee +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = -class OnigScanner - @create: (sources) -> - scanner = $onigScanner.buildScanner(sources) - scanner.constructor = OnigScanner - scanner.__proto__ = OnigScanner.prototype - scanner.sources = sources - scanner - - findNextMatch: $onigScanner.findNextMatch diff --git a/src/stdlib/path.coffee b/src/stdlib/path.coffee deleted file mode 100644 index 337b60d6b..000000000 --- a/src/stdlib/path.coffee +++ /dev/null @@ -1,15 +0,0 @@ -# node.js path module -# http://nodejs.org/docs/v0.6.0/api/path.html - -_ = require 'underscore' - -module.exports = - # Return the last portion of a path. Similar to the Unix basename command. - basename: (filepath) -> - _.last filepath.split '/' - - # Return the extension of the path, from the last '.' to end of string in - # the last portion of the path. If there is no '.' in the last portion of - # the path or the first character of it is '.', then it returns an empty string. - extname: (filepath) -> - _.last filepath.split '.' diff --git a/src/stdlib/require.coffee b/src/stdlib/require.coffee deleted file mode 100644 index 42f0f05b3..000000000 --- a/src/stdlib/require.coffee +++ /dev/null @@ -1,186 +0,0 @@ -paths = [ - "#{window.resourcePath}/spec" - "#{window.resourcePath}/benchmark" - "#{window.resourcePath}/src/stdlib" - "#{window.resourcePath}/src/app" - "#{window.resourcePath}/src/packages" - "#{window.resourcePath}/src" - "#{window.resourcePath}/vendor/packages" - "#{window.resourcePath}/vendor" - "#{window.resourcePath}/static" - "#{window.resourcePath}/themes" - "#{window.resourcePath}" -] - -window.__filename = null - -nakedLoad = (file) -> - file = resolve file - code = __read file - window.eval(code + "\n//@ sourceURL=" + file) - -require = (path, cb) -> - return cb require path if cb? - - unless file = resolve(path) - throw new Error("Require can't find file at path '#{path}'") - - ext = file.split('.').pop() - - if __moduleExists file - if not __modules.loaded[file.toLowerCase()]? - console.warn "Circular require: #{window.__filename} required #{file}" - return __modules[file] - else if __modules.loaded[file.toLowerCase()] - console.warn "Multiple requires (different cases) for #{file}" - - [ previousFilename, window.__filename ] = [ window.__filename, file ] - __modules[file] = {} # Fix for circular references - __modules[file] = (exts[ext] or (file) -> __read file) file - window.__filename = previousFilename - __modules[file] - -define = (cb) -> - __defines.push -> - exports = __modules[window.__filename] or {} - module = exports: exports - cb.call exports, require, exports, module - __modules.loaded[window.__filename.toLowerCase()] = true - module.exports or exports - -exts = - js: (file, code) -> - code or= __read file - eval("define(function(require, exports, module) { 'use strict';#{code}})\n//@ sourceURL=#{file}") - __defines.pop()?.call() - coffee: (file) -> - cacheFilePath = getCacheFilePath(file) - if __exists(cacheFilePath) - compiled = __read(cacheFilePath) - writeToCache = false - else - {CoffeeScript} = require 'coffee-script' - compiled = CoffeeScript.compile(__read(file), filename: file) - writeToCache = true - - evaluated = exts.js(file, compiled) - $native.write(cacheFilePath, compiled) if writeToCache - evaluated - less: (file) -> - output = "" - (new less.Parser).parse __read(file), (e, tree) -> - throw new Error(e.message, file, e.line) if e - output = tree.toCSS() - output - - -getPath = (path) -> - path = resolve(path) - return path unless path.split('.').pop() is 'coffee' - - cacheFilePath = getCacheFilePath(path) - unless __exists(cacheFilePath) - {CoffeeScript} = require 'coffee-script' - compiled = CoffeeScript.compile(__read(path), filename: path) - $native.write(cacheFilePath, compiled) - cacheFilePath - -getCacheFilePath = (path) -> - "/tmp/atom-compiled-scripts/#{$native.md5ForPath(path)}" - -resolve = (name, {verifyExistence}={}) -> - verifyExistence ?= true - file = name - if /!/.test file - file = file.split('!').pop() - - if file[0..1] is './' - prefix = window.__filename.split('/')[0..-2].join '/' - file = file.replace './', "#{prefix}/" - - if file[0..2] is '../' - prefix = window.__filename.split('/')[0..-3].join '/' - file = file.replace '../', "#{prefix}/" - - if file[0] isnt '/' - moduleAlreadyLoaded = paths.some (path) -> - if __moduleExists "#{path}/#{file}" - file = "#{path}/#{file}" - else if __moduleExists "#{path}/#{file}.js" - file = "#{path}/#{file}.js" - else if expanded = __moduleExpand "#{path}/#{file}" - file = expanded - - if not moduleAlreadyLoaded - hasExtension = /\.(.+)$/.test(file) - paths.some (path) -> - fileExists = hasExtension and __exists "#{path}/#{file}" - jsFileExists = not hasExtension and __exists "#{path}/#{file}.js" - - if jsFileExists - file = "#{path}/#{file}.js" - else if fileExists - file = "#{path}/#{file}" - else if expanded = __expand "#{path}/#{file}" - file = expanded - else - file = __expand(file) or file - - if file[0] == '/' - file - else - console.warn("Failed to resolve '#{name}'") if verifyExistence - null - -__moduleExists = (path) -> - __modules[path]? - -__moduleExpand = (path) -> - return path if __moduleExists path - for ext, handler of exts - return "#{path}.#{ext}" if __moduleExists "#{path}.#{ext}" - return "#{path}/index.#{ext}" if __moduleExists "#{path}/index.#{ext}" - null - -__expand = (path) -> - modulePath = __moduleExpand path - return modulePath if modulePath - - return path if __isFile path - for ext, handler of exts - return "#{path}.#{ext}" if __exists "#{path}.#{ext}" - return "#{path}/index.#{ext}" if __exists "#{path}/index.#{ext}" - - return path if __exists path - null - -__exists = (path) -> - $native.exists path - -__isFile = (path) -> - $native.isFile path - -__read = (path) -> - try - $native.read(path) - catch e - console.error "Failed to read `#{path}`" - throw e - -__modules = { loaded : {} } -__defines = [] - -this.require = require -this.nakedLoad = nakedLoad -this.define = define - -this.require.paths = paths -this.require.getPath = getPath -this.require.exts = exts - -this.require.resolve = resolve -this.require.nameToUrl = (path) -> "#{path}.js" -this.require.__modules = __modules - -# issue #17 -this.require.noWorker = true diff --git a/src/stdlib/settings.coffee b/src/stdlib/settings.coffee deleted file mode 100644 index 21961f5ce..000000000 --- a/src/stdlib/settings.coffee +++ /dev/null @@ -1,55 +0,0 @@ -fs = require 'fs' -{CoffeeScript} = require 'coffee-script' - -# Settings file looks like: -# editor: # name of class -# theme: "twilight" -# tabSize: 2 -# softTabs: true -# showInvisibles: false -# -# project: -# ignorePattern: /x|y|z/ -# -# Settings are applied to object x's settings variable by calling applyTo(x) on -# instance of Settings. -module.exports = -class Settings - settings: {} - - load: (path) -> - path = require.resolve path - if not fs.isFile path - console.warn "Could not find settings file '#{path}'" - return - - try - json = CoffeeScript.eval "return " + (fs.read path) - - for className, value of json - @settings[@simplifyClassName className] = value - catch error - console.error "Can't evaluate settings at `#{path}`." - console.error error - - applyTo: (object) -> - if not object.settings - console.warning "#{object.constructor.name}: Does not have `settings` varible" - return - - classHierarchy = [] - - # ICK: Using internal var __super to get the build heirarchy - walker = object - while walker - classHierarchy.unshift @simplifyClassName walker.constructor.name - walker = walker.constructor.__super__ - - for className in classHierarchy - for setting, value of @settings[className] ? {} - object.settings[setting] = value - - # I don't care if you use camelCase, underscores or dashes. It should all - # point to the same place - simplifyClassName: (className) -> - className.toLowerCase().replace /\W/, '' diff --git a/src/stdlib/storage.coffee b/src/stdlib/storage.coffee deleted file mode 100644 index 9a3334b29..000000000 --- a/src/stdlib/storage.coffee +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = -class Storage - storagePath: (require.resolve '~/.atom/.storage') - - get: (key, defaultValue=null) -> - try - value = @storage().valueForKeyPath key - @toJS value or defaultValue - catch error - error.message += "\nGetting #{key}" - console.error(error) - - set: (key, value) -> - keys = key.split '.' - parent = storage = @storage() - for key in keys.slice 0, -1 - parent[key] = {} unless parent[key] - parent = parent[key] - - parent[keys.slice -1] = value - storage.writeToFile_atomically @storagePath, true - - storage: -> - storage = OSX.NSMutableDictionary.dictionaryWithContentsOfFile @storagePath - storage ?= OSX.NSMutableDictionary.dictionary - - toJS: (value) -> - if not value or not value.isKindOfClass - value - else if value.isKindOfClass OSX.NSDictionary.class - dict = {} - dict[k.valueOf()] = @toJS v for k, v of value - dict - else if value.isKindOfClass OSX.NSArray.class - array = [] - array.push @toJS v for v in value - array - else - value.valueOf() diff --git a/src/stdlib/task-shell.coffee b/src/stdlib/task-shell.coffee index 458235e56..6ac2d5f6e 100644 --- a/src/stdlib/task-shell.coffee +++ b/src/stdlib/task-shell.coffee @@ -1,16 +1,17 @@ -# This file is loaded within Task's worker thread. It will attempt to invoke +# This file is loaded within Task's worker process. It will attempt to invoke # any message with a 'method' and 'args' key on the global `handler` object. The # initial `handler` object contains the `start` method, which is called by the # task itself to relay information from the window thread and bootstrap the # worker's environment. The `start` method then replaces the handler with an # object required from the given `handlerPath`. -self.window = {} -self.attachEvent = -> -self.console = +global.window = {} +global.attachEvent = -> +console = warn: -> callTaskMethod 'warn', arguments... log: -> callTaskMethod 'log', arguments... error: -> callTaskMethod 'error', arguments... +global.__defineGetter__ 'console', -> console window.document = createElement: -> @@ -23,23 +24,21 @@ window.document = getElementById: -> {} createComment: -> {} createDocumentFragment: -> {} -self.document = window.document +global.document = window.document # `callTaskMethod` can be used to invoke method's on the parent `Task` object # back in the window thread. -self.callTaskMethod = (method, args...) -> - postMessage(method: method, args: args) +global.callTaskMethod = (method, args...) -> + process.send(method: method, args: args) -# The worker's initial handler replaces itself when `start` is invoked -self.handler = - start: ({resourcePath, globals, requirePath, handlerPath}) -> +# The worker's initial handler replaces itglobal when `start` is invoked +global.handler = + start: ({globals, handlerPath}) -> for key, value of globals - self[key] = value + global[key] = value window[key] = value - importScripts(requirePath) - require 'config' - self.handler = require(handlerPath) + global.handler = require(handlerPath) callTaskMethod 'started' -self.addEventListener 'message', ({data}) -> +process.on 'message', (data) -> handler[data.method]?(data.args...) if data.method diff --git a/src/stdlib/task.coffee b/src/stdlib/task.coffee index eb3e2f3f5..8216a4f15 100644 --- a/src/stdlib/task.coffee +++ b/src/stdlib/task.coffee @@ -1,5 +1,7 @@ _ = require 'underscore' +child_process = require 'child_process' EventEmitter = require 'event-emitter' +fs = require 'fs-utils' module.exports = class Task @@ -10,8 +12,11 @@ class Task start: -> throw new Error("Task already started") if @worker? - @worker = new Worker(require.getPath('task-shell')) - @worker.onmessage = ({data}) => + # Equivalent with node --eval "...". + blob = "require('coffee-script'); require('task-shell');" + @worker = child_process.fork '--eval', [ blob ], cwd: __dirname + + @worker.on 'message', (data) => if @aborted @done() return @@ -20,6 +25,7 @@ class Task this[data.method](data.args...) else @onMessage(data) + @startWorker() log: -> console.log(arguments...) @@ -29,10 +35,8 @@ class Task startWorker: -> @callWorkerMethod 'start', globals: - resourcePath: window.resourcePath navigator: userAgent: navigator.userAgent - requirePath: require.getPath('require') handlerPath: @path started: -> @@ -43,14 +47,14 @@ class Task @postMessage({method, args}) postMessage: (data) -> - @worker.postMessage(data) + @worker.send(data) abort: -> @aborted = true done: -> @abort() - @worker?.terminate() + @worker?.kill() @worker = null @trigger 'task-completed' diff --git a/src/stdlib/underscore-extensions.coffee b/src/stdlib/underscore-extensions.coffee index df5865b24..33dde9f48 100644 --- a/src/stdlib/underscore-extensions.coffee +++ b/src/stdlib/underscore-extensions.coffee @@ -52,16 +52,20 @@ _.mixin regex = RegExp('[' + specials.join('\\') + ']', 'g') string.replace(regex, "\\$&"); - humanizeEventName: (eventName) -> - if /:/.test(eventName) - [namespace, name] = eventName.split(':') - return "#{@humanizeEventName(namespace)}: #{@humanizeEventName(name)}" + humanizeEventName: (eventName, eventDoc) -> + [namespace, event] = eventName.split(':') + return _.capitalize(namespace) unless event? - words = eventName.split('-') - words.map(_.capitalize).join(' ') + namespaceDoc = _.undasherize(namespace) + eventDoc ?= _.undasherize(event) + + "#{namespaceDoc}: #{eventDoc}" capitalize: (word) -> - word[0].toUpperCase() + word[1..] + if word.toLowerCase() is 'github' + 'GitHub' + else + word[0].toUpperCase() + word[1..] pluralize: (count=0, singular, plural=singular+'s') -> if count is 1 @@ -80,6 +84,9 @@ _.mixin else "-" + undasherize: (string) -> + string.split('-').map(_.capitalize).join(' ') + underscore: (string) -> string = string[0].toLowerCase() + string[1..] string.replace /([A-Z])|(-)/g, (m, letter, dash) -> @@ -131,3 +138,53 @@ _.mixin for key, value of object newObject[key] = value if value? newObject + +originalIsEqual = _.isEqual +extendedIsEqual = (a, b, aStack=[], bStack=[]) -> + return originalIsEqual(a, b) if a is b + return originalIsEqual(a, b) if _.isFunction(a) or _.isFunction(b) + return a.isEqual(b) if _.isFunction(a?.isEqual) + return b.isEqual(a) if _.isFunction(b?.isEqual) + + stackIndex = aStack.length + while stackIndex-- + return bStack[stackIndex] is b if aStack[stackIndex] is a + aStack.push(a) + bStack.push(b) + + equal = false + if _.isArray(a) and _.isArray(b) and a.length is b.length + equal = true + for aElement, i in a + unless extendedIsEqual(aElement, b[i], aStack, bStack) + equal = false + break + else if _.isObject(a) and _.isObject(b) + aCtor = a.constructor + bCtor = b.constructor + aCtorValid = _.isFunction(aCtor) and aCtor instanceof aCtor + bCtorValid = _.isFunction(bCtor) and bCtor instanceof bCtor + if aCtor isnt bCtor and not (aCtorValid and bCtorValid) + equal = false + else + aKeyCount = 0 + equal = true + for key, aValue of a + continue unless _.has(a, key) + aKeyCount++ + unless _.has(b, key) and extendedIsEqual(aValue, b[key], aStack, bStack) + equal = false + break + if equal + bKeyCount = 0 + for key, bValue of b + bKeyCount++ if _.has(b, key) + equal = aKeyCount is bKeyCount + else + equal = originalIsEqual(a, b) + + aStack.pop() + bStack.pop() + equal + +_.isEqual = (a, b) -> extendedIsEqual(a, b) diff --git a/src/stdlib/watcher.coffee b/src/stdlib/watcher.coffee deleted file mode 100644 index 2ea02ff96..000000000 --- a/src/stdlib/watcher.coffee +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = -class Watcher - @watchedPaths: {} - - @setup: -> - if not OSX.__AAWatcher__ - OSX.__AAWatcher__ = OSX.JSCocoa.createClass_parentClass "__AAWatcher__", "NSObject" - OSX.JSCocoa.addInstanceMethod_class_jsFunction_encoding "watcher:receivedNotification:forPath:", OSX.__AAWatcher__, @watcher_receivedNotification_forPath, "v:@@@@" - - @delegate = OSX.__AAWatcher__.alloc.init - @queue = OSX.UKKQueue.alloc.init - @queue.setDelegate @delegate - - @watch: (path, callback) -> - @setup() unless @queue? - - path = OSX.NSString.stringWithString(path).stringByStandardizingPath - @queue.addPath path if not @watchedPaths[path] - - (@watchedPaths[path] ?= []).push callback - - callback # Handy for anonymous functions. - - @unwatch: (path, callback=null) -> - return unless @watchedPaths[path] - - @watchedPaths[path] = (item for item in @watchedPaths[path] when item != callback) - if not callback? or @watchedPaths[path].length == 0 - @watchedPaths[path] = null - console.log "Unwatch #{path}" - @queue.removePathFromQueue path - - # Delegate method for __AAWatcher__ - @watcher_receivedNotification_forPath = (queue, notification, path) => - callbacks = @watchedPaths[path] ? [] - - switch notification.toString() - when "UKKQueueFileRenamedNotification" - throw "Doesn't handle this yet" - when "UKKQueueFileDeletedNotification" - @watchedPaths[path] = null - @queue.removePathFromQueue path - callback notification, path, callback for callback in callbacks - when "UKKQueueFileWrittenToNotification" - callback notification, path, callback for callback in callbacks - when "UKKQueueFileAttributesChangedNotification" - # Just ignore this - console.log "Attribute Changed on #{path}" - else - console.error "I HAVE NO IDEA WHY #{notification} WAS TRIGGERED ON #{path}" diff --git a/static/editor.less b/static/editor.less index c88b3f1f2..c9ab251fa 100644 --- a/static/editor.less +++ b/static/editor.less @@ -1,6 +1,7 @@ .editor { overflow: hidden; cursor: text; + display: -webkit-flex; -webkit-user-select: none; position: relative; z-index: 0; @@ -24,19 +25,18 @@ } .editor .gutter { - position: absolute; - height: 100%; overflow: hidden; text-align: right; cursor: default; + min-width: 1em; + box-sizing: border-box; + text-align: right; + opacity: 0.6; } .editor .gutter .line-number { padding-right: .5em; - min-width: 35px; - box-sizing: border-box; - text-align: right; - opacity: 0.6; + padding-left: .5em; } .editor .gutter .line-numbers { @@ -104,13 +104,11 @@ } .editor .scroll-view { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; overflow-x: auto; overflow-y: hidden; + -webkit-flex: 1; + min-width: 0; + position: relative; } .editor.mini .scroll-view { diff --git a/static/index.html b/static/index.html index 0e27bf115..9ef2362ab 100644 --- a/static/index.html +++ b/static/index.html @@ -16,6 +16,8 @@ window.onload = function() { try { + require('coffee-script'); + require('coffee-cache').setCacheDir('/tmp/atom-coffee-cache'); if (bootstrapScript) require(bootstrapScript); } catch (error) { @@ -24,8 +26,6 @@ } } - - diff --git a/static/mac.css b/static/mac.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/static/octicons-regular-webfont.woff b/static/octicons-regular-webfont.woff index b4516588c..2ba436bd5 100644 Binary files a/static/octicons-regular-webfont.woff and b/static/octicons-regular-webfont.woff differ diff --git a/static/reset.less b/static/reset.less old mode 100755 new mode 100644 diff --git a/static/tree-view.less b/static/tree-view.less deleted file mode 100644 index df692daa9..000000000 --- a/static/tree-view.less +++ /dev/null @@ -1,135 +0,0 @@ -.tree-view .entries { - margin-left: 12px; -} - -.tree-view .entries .file .name { - margin-left: 20px; -} - -.tree-view .file .name, -.tree-view .directory .header { - padding-top: 4px; - padding-bottom: 4px; - padding-right: 10px; -} - -.tree-view .directory .header { - padding-left: 5px; -} - -.tree-view-dialog { - padding: 5px; -} - -.tree-view-dialog .prompt { - padding-bottom: 3px; - font-size: 12px; - line-height: 16px; -} - -.tree-view-dialog .prompt span { - position: relative; - top: -1px; -} - -.tree-view-dialog .prompt:before { - font-family: 'Octicons Regular'; - font-size: 16px; - width: 16px; - height: 16px; - margin-right: 3px; - -webkit-font-smoothing: antialiased; -} - -.tree-view-dialog .prompt.add-file:before { - content: "\f086"; -} - -.tree-view-dialog .prompt.add-directory:before { - content: "\f095"; -} - -.tree-view-dialog .prompt.move:before { - content: "\f03e"; -} - -.tree-view .directory .header .name, -.tree-view .file .name { - position: relative; - padding-left: 21px; -} - -.tree-view .directory .header .name:before, -.tree-view .file .name:before { - font-family: 'Octicons Regular'; - font-size: 16px; - width: 16px; - height: 16px; - margin-right: 5px; - -webkit-font-smoothing: antialiased; - position: absolute; - left: 0; -} - -.tree-view .disclosure-arrow:before { - font-family: 'Octicons Regular'; - font-size: 12px; - width: 12px; - height: 12px; - line-height: 16px; - margin-right: 3px; - -webkit-font-smoothing: antialiased; -} - -.tree-view .directory .header .directory-icon:before { - content: "\f016"; - top: -5px; -} - -.tree-view .directory .header .repository-icon:before { - content: "\f001"; - top: -4px; -} - -.tree-view .directory .header .submodule-icon:before { - content: "\f017"; - top: -5px; -} - -.tree-view .file .text-icon:before { - content: "\f011"; - top: -2px; -} - -.tree-view .file .image-icon:before { - content: "\f012"; - top: -2px; -} - -.tree-view .file .compressed-icon:before { - content: "\f013"; - top: -2px; -} - -.tree-view .file .pdf-icon:before { - content: "\f014"; - top: -2px; -} - -.tree-view .file .readme-icon:before { - content: "\f007"; - top: -2px; -} - -.tree-view .file .binary-icon:before { - content: "\f094"; - top: -2px; -} - -.tree-view .directory > .header .disclosure-arrow:before { - content: "\f05a"; -} - -.tree-view .directory.expanded > .header .disclosure-arrow:before { - content: "\f05b"; -} diff --git a/themes/atom-dark-ui/status-bar.css b/themes/atom-dark-ui/status-bar.css index 1c0af57e0..3ab4934e6 100644 --- a/themes/atom-dark-ui/status-bar.css +++ b/themes/atom-dark-ui/status-bar.css @@ -20,3 +20,8 @@ color: #5293d8; display: inline-block; } + +.status-bar .git-status.octicons.ignored-status-icon { + color: #969696; + display: inline-block; +} diff --git a/themes/atom-light-ui/status-bar.css b/themes/atom-light-ui/status-bar.css index 145d90845..2ef7d2ae9 100644 --- a/themes/atom-light-ui/status-bar.css +++ b/themes/atom-light-ui/status-bar.css @@ -14,6 +14,11 @@ display: inline-block; } +.status-bar .git-status.octicons.ignored-status-icon { + color: #333; + display: inline-block; +} + .status-bar .grammar-name:hover { color: #000; border: 1px solid rgba(50, 50, 50, 0.2); diff --git a/vendor/assert.js b/vendor/assert.js deleted file mode 100644 index 41e208069..000000000 --- a/vendor/assert.js +++ /dev/null @@ -1,325 +0,0 @@ -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.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 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. - -// UTILITY -// var util = require('util'); -var pSlice = Array.prototype.slice; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = exports; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -// util.inherits(assert.AssertionError, Error); - -function replacer(key, value) { - if (value === undefined) { - return '' + value; - } - if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) { - return value.toString(); - } - if (typeof value === 'function' || value instanceof RegExp) { - return value.toString(); - } - return value; -} - -function truncate(s, n) { - if (typeof s == 'string') { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [ this.name + ':', this.message ].join(' '); - } else { - return [ - this.name + ':', - truncate(JSON.stringify(this.actual, replacer), 128), - this.operator, - truncate(JSON.stringify(this.expected, replacer), 128) - ].join(' '); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -assert.ok = function ok(value, message) { - if (!!!value) fail(value, true, message, '==', assert.ok); -}; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { - if (actual.length != expected.length) return false; - - for (var i = 0; i < actual.length; i++) { - if (actual[i] !== expected[i]) return false; - } - - return true; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try { - var ka = Object.keys(a), - kb = Object.keys(b), - key, i; - } catch (e) {//happens when one is a string literal and the other isn't - return false; - } - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key])) return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (expected instanceof RegExp) { - return expected.test(actual); - } else if (actual instanceof expected) { - return true; - } else if (expected.call({}, actual) === true) { - return true; - } - - return false; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail('Missing expected exception' + message); - } - - if (!shouldThrow && expectedException(actual, expected)) { - fail('Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function(err) { if (err) {throw err;}}; diff --git a/vendor/coffee-script.js b/vendor/coffee-script.js deleted file mode 100644 index 18d9e9010..000000000 --- a/vendor/coffee-script.js +++ /dev/null @@ -1,4642 +0,0 @@ -// MODIFIED: -// Generated with `MINIFY=false cake build:browser` from CoffeeScript source -// Removed call to `define` at end of file so our wrapper kicks in - -/** - * CoffeeScript Compiler v1.2.0 - * http://coffeescript.org - * - * Copyright 2011, Jeremy Ashkenas - * Released under the MIT License - */ -(function(root) { - var CoffeeScript = function() { - function require(path){ return require[path]; } - require['./helpers'] = new function() { - var exports = this; - (function() { - var extend, flatten; - - exports.starts = function(string, literal, start) { - return literal === string.substr(start, literal.length); - }; - - exports.ends = function(string, literal, back) { - var len; - len = literal.length; - return literal === string.substr(string.length - len - (back || 0), len); - }; - - exports.compact = function(array) { - var item, _i, _len, _results; - _results = []; - for (_i = 0, _len = array.length; _i < _len; _i++) { - item = array[_i]; - if (item) _results.push(item); - } - return _results; - }; - - exports.count = function(string, substr) { - var num, pos; - num = pos = 0; - if (!substr.length) return 1 / 0; - while (pos = 1 + string.indexOf(substr, pos)) { - num++; - } - return num; - }; - - exports.merge = function(options, overrides) { - return extend(extend({}, options), overrides); - }; - - extend = exports.extend = function(object, properties) { - var key, val; - for (key in properties) { - val = properties[key]; - object[key] = val; - } - return object; - }; - - exports.flatten = flatten = function(array) { - var element, flattened, _i, _len; - flattened = []; - for (_i = 0, _len = array.length; _i < _len; _i++) { - element = array[_i]; - if (element instanceof Array) { - flattened = flattened.concat(flatten(element)); - } else { - flattened.push(element); - } - } - return flattened; - }; - - exports.del = function(obj, key) { - var val; - val = obj[key]; - delete obj[key]; - return val; - }; - - exports.last = function(array, back) { - return array[array.length - (back || 0) - 1]; - }; - -}).call(this); - -};require['./rewriter'] = new function() { - var exports = this; - (function() { - var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref, - __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = Array.prototype.slice; - - exports.Rewriter = (function() { - - function Rewriter() {} - - Rewriter.prototype.rewrite = function(tokens) { - this.tokens = tokens; - this.removeLeadingNewlines(); - this.removeMidExpressionNewlines(); - this.closeOpenCalls(); - this.closeOpenIndexes(); - this.addImplicitIndentation(); - this.tagPostfixConditionals(); - this.addImplicitBraces(); - this.addImplicitParentheses(); - return this.tokens; - }; - - Rewriter.prototype.scanTokens = function(block) { - var i, token, tokens; - tokens = this.tokens; - i = 0; - while (token = tokens[i]) { - i += block.call(this, token, i, tokens); - } - return true; - }; - - Rewriter.prototype.detectEnd = function(i, condition, action) { - var levels, token, tokens, _ref, _ref2; - tokens = this.tokens; - levels = 0; - while (token = tokens[i]) { - if (levels === 0 && condition.call(this, token, i)) { - return action.call(this, token, i); - } - if (!token || levels < 0) return action.call(this, token, i - 1); - if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) { - levels += 1; - } else if (_ref2 = token[0], __indexOf.call(EXPRESSION_END, _ref2) >= 0) { - levels -= 1; - } - i += 1; - } - return i - 1; - }; - - Rewriter.prototype.removeLeadingNewlines = function() { - var i, tag, _len, _ref; - _ref = this.tokens; - for (i = 0, _len = _ref.length; i < _len; i++) { - tag = _ref[i][0]; - if (tag !== 'TERMINATOR') break; - } - if (i) return this.tokens.splice(0, i); - }; - - Rewriter.prototype.removeMidExpressionNewlines = function() { - return this.scanTokens(function(token, i, tokens) { - var _ref; - if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) { - return 1; - } - tokens.splice(i, 1); - return 0; - }); - }; - - Rewriter.prototype.closeOpenCalls = function() { - var action, condition; - condition = function(token, i) { - var _ref; - return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')'; - }; - action = function(token, i) { - return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END'; - }; - return this.scanTokens(function(token, i) { - if (token[0] === 'CALL_START') this.detectEnd(i + 1, condition, action); - return 1; - }); - }; - - Rewriter.prototype.closeOpenIndexes = function() { - var action, condition; - condition = function(token, i) { - var _ref; - return (_ref = token[0]) === ']' || _ref === 'INDEX_END'; - }; - action = function(token, i) { - return token[0] = 'INDEX_END'; - }; - return this.scanTokens(function(token, i) { - if (token[0] === 'INDEX_START') this.detectEnd(i + 1, condition, action); - return 1; - }); - }; - - Rewriter.prototype.addImplicitBraces = function() { - var action, condition, sameLine, stack, start, startIndent, startsLine; - stack = []; - start = null; - startsLine = null; - sameLine = true; - startIndent = 0; - condition = function(token, i) { - var one, tag, three, two, _ref, _ref2; - _ref = this.tokens.slice(i + 1, (i + 3) + 1 || 9e9), one = _ref[0], two = _ref[1], three = _ref[2]; - if ('HERECOMMENT' === (one != null ? one[0] : void 0)) return false; - tag = token[0]; - if (__indexOf.call(LINEBREAKS, tag) >= 0) sameLine = false; - return (((tag === 'TERMINATOR' || tag === 'OUTDENT') || (__indexOf.call(IMPLICIT_END, tag) >= 0 && sameLine)) && ((!startsLine && this.tag(i - 1) !== ',') || !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':'))) || (tag === ',' && one && ((_ref2 = one[0]) !== 'IDENTIFIER' && _ref2 !== 'NUMBER' && _ref2 !== 'STRING' && _ref2 !== '@' && _ref2 !== 'TERMINATOR' && _ref2 !== 'OUTDENT')); - }; - action = function(token, i) { - var tok; - tok = ['}', '}', token[2]]; - tok.generated = true; - return this.tokens.splice(i, 0, tok); - }; - return this.scanTokens(function(token, i, tokens) { - var ago, idx, prevTag, tag, tok, value, _ref, _ref2; - if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) { - stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]); - return 1; - } - if (__indexOf.call(EXPRESSION_END, tag) >= 0) { - start = stack.pop(); - return 1; - } - if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref2 = stack[stack.length - 1]) != null ? _ref2[0] : void 0) !== '{'))) { - return 1; - } - sameLine = true; - stack.push(['{']); - idx = ago === '@' ? i - 2 : i - 1; - while (this.tag(idx - 2) === 'HERECOMMENT') { - idx -= 2; - } - prevTag = this.tag(idx - 1); - startsLine = !prevTag || (__indexOf.call(LINEBREAKS, prevTag) >= 0); - value = new String('{'); - value.generated = true; - tok = ['{', value, token[2]]; - tok.generated = true; - tokens.splice(idx, 0, tok); - this.detectEnd(i + 2, condition, action); - return 2; - }); - }; - - Rewriter.prototype.addImplicitParentheses = function() { - var action, condition, noCall, seenControl, seenSingle; - noCall = seenSingle = seenControl = false; - condition = function(token, i) { - var post, tag, _ref, _ref2; - tag = token[0]; - if (!seenSingle && token.fromThen) return true; - if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>' || tag === 'CLASS') { - seenSingle = true; - } - if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY' || tag === '=') { - seenControl = true; - } - if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') { - return true; - } - return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref2 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref2) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{'))); - }; - action = function(token, i) { - return this.tokens.splice(i, 0, ['CALL_END', ')', token[2]]); - }; - return this.scanTokens(function(token, i, tokens) { - var callObject, current, next, prev, tag, _ref, _ref2, _ref3; - tag = token[0]; - if (tag === 'CLASS' || tag === 'IF') noCall = true; - _ref = tokens.slice(i - 1, (i + 1) + 1 || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2]; - callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0); - seenSingle = false; - seenControl = false; - if (__indexOf.call(LINEBREAKS, tag) >= 0) noCall = false; - if (prev && !prev.spaced && tag === '?') token.call = true; - if (token.fromThen) return 1; - if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref3 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref3) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) { - return 1; - } - tokens.splice(i, 0, ['CALL_START', '(', token[2]]); - this.detectEnd(i + 1, condition, action); - if (prev[0] === '?') prev[0] = 'FUNC_EXIST'; - return 2; - }); - }; - - Rewriter.prototype.addImplicitIndentation = function() { - var action, condition, indent, outdent, starter; - starter = indent = outdent = null; - condition = function(token, i) { - var _ref; - return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN')); - }; - action = function(token, i) { - return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent); - }; - return this.scanTokens(function(token, i, tokens) { - var tag, _ref, _ref2; - tag = token[0]; - if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') { - tokens.splice(i, 1); - return 0; - } - if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { - tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token)))); - return 2; - } - if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) { - tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token)))); - return 4; - } - if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { - starter = tag; - _ref2 = this.indentation(token), indent = _ref2[0], outdent = _ref2[1]; - if (starter === 'THEN') indent.fromThen = true; - indent.generated = outdent.generated = true; - tokens.splice(i + 1, 0, indent); - this.detectEnd(i + 2, condition, action); - if (tag === 'THEN') tokens.splice(i, 1); - return 1; - } - return 1; - }); - }; - - Rewriter.prototype.tagPostfixConditionals = function() { - var action, condition, original; - original = null; - condition = function(token, i) { - var _ref; - return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT'; - }; - action = function(token, i) { - if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) { - return original[0] = 'POST_' + original[0]; - } - }; - return this.scanTokens(function(token, i) { - if (token[0] !== 'IF') return 1; - original = token; - this.detectEnd(i + 1, condition, action); - return 1; - }); - }; - - Rewriter.prototype.indentation = function(token) { - return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]]; - }; - - Rewriter.prototype.tag = function(i) { - var _ref; - return (_ref = this.tokens[i]) != null ? _ref[0] : void 0; - }; - - return Rewriter; - - })(); - - BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']]; - - exports.INVERSES = INVERSES = {}; - - EXPRESSION_START = []; - - EXPRESSION_END = []; - - for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) { - _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1]; - EXPRESSION_START.push(INVERSES[rite] = left); - EXPRESSION_END.push(INVERSES[left] = rite); - } - - EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); - - IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; - - IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++']; - - IMPLICIT_UNSPACED_CALL = ['+', '-']; - - IMPLICIT_BLOCK = ['->', '=>', '{', '[', ',']; - - IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR']; - - SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; - - SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']; - - LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; - -}).call(this); - -};require['./lexer'] = new function() { - var exports = this; - (function() { - var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref2, - __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES; - - _ref2 = require('./helpers'), count = _ref2.count, starts = _ref2.starts, compact = _ref2.compact, last = _ref2.last; - - exports.Lexer = Lexer = (function() { - - function Lexer() {} - - Lexer.prototype.tokenize = function(code, opts) { - var i, tag; - if (opts == null) opts = {}; - if (WHITESPACE.test(code)) code = "\n" + code; - code = code.replace(/\r/g, '').replace(TRAILING_SPACES, ''); - this.code = code; - this.line = opts.line || 0; - this.indent = 0; - this.indebt = 0; - this.outdebt = 0; - this.indents = []; - this.ends = []; - this.tokens = []; - i = 0; - while (this.chunk = code.slice(i)) { - i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); - } - this.closeIndentation(); - if (tag = this.ends.pop()) this.error("missing " + tag); - if (opts.rewrite === false) return this.tokens; - return (new Rewriter).rewrite(this.tokens); - }; - - Lexer.prototype.identifierToken = function() { - var colon, forcedIdentifier, id, input, match, prev, tag, _ref3, _ref4; - if (!(match = IDENTIFIER.exec(this.chunk))) return 0; - input = match[0], id = match[1], colon = match[2]; - if (id === 'own' && this.tag() === 'FOR') { - this.token('OWN', id); - return id.length; - } - forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref3 = prev[0]) === '.' || _ref3 === '?.' || _ref3 === '::') || !prev.spaced && prev[0] === '@'); - tag = 'IDENTIFIER'; - if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) { - tag = id.toUpperCase(); - if (tag === 'WHEN' && (_ref4 = this.tag(), __indexOf.call(LINE_BREAK, _ref4) >= 0)) { - tag = 'LEADING_WHEN'; - } else if (tag === 'FOR') { - this.seenFor = true; - } else if (tag === 'UNLESS') { - tag = 'IF'; - } else if (__indexOf.call(UNARY, tag) >= 0) { - tag = 'UNARY'; - } else if (__indexOf.call(RELATION, tag) >= 0) { - if (tag !== 'INSTANCEOF' && this.seenFor) { - tag = 'FOR' + tag; - this.seenFor = false; - } else { - tag = 'RELATION'; - if (this.value() === '!') { - this.tokens.pop(); - id = '!' + id; - } - } - } - } - if (__indexOf.call(['eval', 'arguments'].concat(JS_FORBIDDEN), id) >= 0) { - if (forcedIdentifier) { - tag = 'IDENTIFIER'; - id = new String(id); - id.reserved = true; - } else if (__indexOf.call(RESERVED, id) >= 0) { - this.error("reserved word \"" + id + "\""); - } - } - if (!forcedIdentifier) { - if (__indexOf.call(COFFEE_ALIASES, id) >= 0) id = COFFEE_ALIAS_MAP[id]; - tag = (function() { - switch (id) { - case '!': - return 'UNARY'; - case '==': - case '!=': - return 'COMPARE'; - case '&&': - case '||': - return 'LOGIC'; - case 'true': - case 'false': - case 'null': - case 'undefined': - return 'BOOL'; - case 'break': - case 'continue': - return 'STATEMENT'; - default: - return tag; - } - })(); - } - this.token(tag, id); - if (colon) this.token(':', ':'); - return input.length; - }; - - Lexer.prototype.numberToken = function() { - var binaryLiteral, lexedLength, match, number; - if (!(match = NUMBER.exec(this.chunk))) return 0; - number = match[0]; - lexedLength = number.length; - if (binaryLiteral = /0b([01]+)/.exec(number)) { - number = (parseInt(binaryLiteral[1], 2)).toString(); - } - this.token('NUMBER', number); - return lexedLength; - }; - - Lexer.prototype.stringToken = function() { - var match, string; - switch (this.chunk.charAt(0)) { - case "'": - if (!(match = SIMPLESTR.exec(this.chunk))) return 0; - this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n')); - break; - case '"': - if (!(string = this.balancedString(this.chunk, '"'))) return 0; - if (0 < string.indexOf('#{', 1)) { - this.interpolateString(string.slice(1, -1)); - } else { - this.token('STRING', this.escapeLines(string)); - } - break; - default: - return 0; - } - this.line += count(string, '\n'); - return string.length; - }; - - Lexer.prototype.heredocToken = function() { - var doc, heredoc, match, quote; - if (!(match = HEREDOC.exec(this.chunk))) return 0; - heredoc = match[0]; - quote = heredoc.charAt(0); - doc = this.sanitizeHeredoc(match[2], { - quote: quote, - indent: null - }); - if (quote === '"' && 0 <= doc.indexOf('#{')) { - this.interpolateString(doc, { - heredoc: true - }); - } else { - this.token('STRING', this.makeString(doc, quote, true)); - } - this.line += count(heredoc, '\n'); - return heredoc.length; - }; - - Lexer.prototype.commentToken = function() { - var comment, here, match; - if (!(match = this.chunk.match(COMMENT))) return 0; - comment = match[0], here = match[1]; - if (here) { - this.token('HERECOMMENT', this.sanitizeHeredoc(here, { - herecomment: true, - indent: Array(this.indent + 1).join(' ') - })); - this.token('TERMINATOR', '\n'); - } - this.line += count(comment, '\n'); - return comment.length; - }; - - Lexer.prototype.jsToken = function() { - var match, script; - if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) { - return 0; - } - this.token('JS', (script = match[0]).slice(1, -1)); - return script.length; - }; - - Lexer.prototype.regexToken = function() { - var flags, length, match, prev, regex, _ref3, _ref4; - if (this.chunk.charAt(0) !== '/') return 0; - if (match = HEREGEX.exec(this.chunk)) { - length = this.heregexToken(match); - this.line += count(match[0], '\n'); - return length; - } - prev = last(this.tokens); - if (prev && (_ref3 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref3) >= 0)) { - return 0; - } - if (!(match = REGEX.exec(this.chunk))) return 0; - _ref4 = match, match = _ref4[0], regex = _ref4[1], flags = _ref4[2]; - if (regex.slice(0, 2) === '/*') { - this.error('regular expressions cannot begin with `*`'); - } - if (regex === '//') regex = '/(?:)/'; - this.token('REGEX', "" + regex + flags); - return match.length; - }; - - Lexer.prototype.heregexToken = function(match) { - var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref3, _ref4, _ref5, _ref6; - heregex = match[0], body = match[1], flags = match[2]; - if (0 > body.indexOf('#{')) { - re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/'); - if (re.match(/^\*/)) { - this.error('regular expressions cannot begin with `*`'); - } - this.token('REGEX', "/" + (re || '(?:)') + "/" + flags); - return heregex.length; - } - this.token('IDENTIFIER', 'RegExp'); - this.tokens.push(['CALL_START', '(']); - tokens = []; - _ref3 = this.interpolateString(body, { - regex: true - }); - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - _ref4 = _ref3[_i], tag = _ref4[0], value = _ref4[1]; - if (tag === 'TOKENS') { - tokens.push.apply(tokens, value); - } else { - if (!(value = value.replace(HEREGEX_OMIT, ''))) continue; - value = value.replace(/\\/g, '\\\\'); - tokens.push(['STRING', this.makeString(value, '"', true)]); - } - tokens.push(['+', '+']); - } - tokens.pop(); - if (((_ref5 = tokens[0]) != null ? _ref5[0] : void 0) !== 'STRING') { - this.tokens.push(['STRING', '""'], ['+', '+']); - } - (_ref6 = this.tokens).push.apply(_ref6, tokens); - if (flags) this.tokens.push([',', ','], ['STRING', '"' + flags + '"']); - this.token(')', ')'); - return heregex.length; - }; - - Lexer.prototype.lineToken = function() { - var diff, indent, match, noNewlines, prev, size; - if (!(match = MULTI_DENT.exec(this.chunk))) return 0; - indent = match[0]; - this.line += count(indent, '\n'); - this.seenFor = false; - prev = last(this.tokens, 1); - size = indent.length - 1 - indent.lastIndexOf('\n'); - noNewlines = this.unfinished(); - if (size - this.indebt === this.indent) { - if (noNewlines) { - this.suppressNewlines(); - } else { - this.newlineToken(); - } - return indent.length; - } - if (size > this.indent) { - if (noNewlines) { - this.indebt = size - this.indent; - this.suppressNewlines(); - return indent.length; - } - diff = size - this.indent + this.outdebt; - this.token('INDENT', diff); - this.indents.push(diff); - this.ends.push('OUTDENT'); - this.outdebt = this.indebt = 0; - } else { - this.indebt = 0; - this.outdentToken(this.indent - size, noNewlines); - } - this.indent = size; - return indent.length; - }; - - Lexer.prototype.outdentToken = function(moveOut, noNewlines) { - var dent, len; - while (moveOut > 0) { - len = this.indents.length - 1; - if (this.indents[len] === void 0) { - moveOut = 0; - } else if (this.indents[len] === this.outdebt) { - moveOut -= this.outdebt; - this.outdebt = 0; - } else if (this.indents[len] < this.outdebt) { - this.outdebt -= this.indents[len]; - moveOut -= this.indents[len]; - } else { - dent = this.indents.pop() - this.outdebt; - moveOut -= dent; - this.outdebt = 0; - this.pair('OUTDENT'); - this.token('OUTDENT', dent); - } - } - if (dent) this.outdebt -= moveOut; - while (this.value() === ';') { - this.tokens.pop(); - } - if (!(this.tag() === 'TERMINATOR' || noNewlines)) { - this.token('TERMINATOR', '\n'); - } - return this; - }; - - Lexer.prototype.whitespaceToken = function() { - var match, nline, prev; - if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) { - return 0; - } - prev = last(this.tokens); - if (prev) prev[match ? 'spaced' : 'newLine'] = true; - if (match) { - return match[0].length; - } else { - return 0; - } - }; - - Lexer.prototype.newlineToken = function() { - while (this.value() === ';') { - this.tokens.pop(); - } - if (this.tag() !== 'TERMINATOR') this.token('TERMINATOR', '\n'); - return this; - }; - - Lexer.prototype.suppressNewlines = function() { - if (this.value() === '\\') this.tokens.pop(); - return this; - }; - - Lexer.prototype.literalToken = function() { - var match, prev, tag, value, _ref3, _ref4, _ref5, _ref6; - if (match = OPERATOR.exec(this.chunk)) { - value = match[0]; - if (CODE.test(value)) this.tagParameters(); - } else { - value = this.chunk.charAt(0); - } - tag = value; - prev = last(this.tokens); - if (value === '=' && prev) { - if (!prev[1].reserved && (_ref3 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref3) >= 0)) { - this.error("reserved word \"" + (this.value()) + "\" can't be assigned"); - } - if ((_ref4 = prev[1]) === '||' || _ref4 === '&&') { - prev[0] = 'COMPOUND_ASSIGN'; - prev[1] += '='; - return value.length; - } - } - if (value === ';') { - this.seenFor = false; - tag = 'TERMINATOR'; - } else if (__indexOf.call(MATH, value) >= 0) { - tag = 'MATH'; - } else if (__indexOf.call(COMPARE, value) >= 0) { - tag = 'COMPARE'; - } else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) { - tag = 'COMPOUND_ASSIGN'; - } else if (__indexOf.call(UNARY, value) >= 0) { - tag = 'UNARY'; - } else if (__indexOf.call(SHIFT, value) >= 0) { - tag = 'SHIFT'; - } else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) { - tag = 'LOGIC'; - } else if (prev && !prev.spaced) { - if (value === '(' && (_ref5 = prev[0], __indexOf.call(CALLABLE, _ref5) >= 0)) { - if (prev[0] === '?') prev[0] = 'FUNC_EXIST'; - tag = 'CALL_START'; - } else if (value === '[' && (_ref6 = prev[0], __indexOf.call(INDEXABLE, _ref6) >= 0)) { - tag = 'INDEX_START'; - switch (prev[0]) { - case '?': - prev[0] = 'INDEX_SOAK'; - } - } - } - switch (value) { - case '(': - case '{': - case '[': - this.ends.push(INVERSES[value]); - break; - case ')': - case '}': - case ']': - this.pair(value); - } - this.token(tag, value); - return value.length; - }; - - Lexer.prototype.sanitizeHeredoc = function(doc, options) { - var attempt, herecomment, indent, match, _ref3; - indent = options.indent, herecomment = options.herecomment; - if (herecomment) { - if (HEREDOC_ILLEGAL.test(doc)) { - this.error("block comment cannot contain \"*/\", starting"); - } - if (doc.indexOf('\n') <= 0) return doc; - } else { - while (match = HEREDOC_INDENT.exec(doc)) { - attempt = match[1]; - if (indent === null || (0 < (_ref3 = attempt.length) && _ref3 < indent.length)) { - indent = attempt; - } - } - } - if (indent) doc = doc.replace(RegExp("\\n" + indent, "g"), '\n'); - if (!herecomment) doc = doc.replace(/^\n/, ''); - return doc; - }; - - Lexer.prototype.tagParameters = function() { - var i, stack, tok, tokens; - if (this.tag() !== ')') return this; - stack = []; - tokens = this.tokens; - i = tokens.length; - tokens[--i][0] = 'PARAM_END'; - while (tok = tokens[--i]) { - switch (tok[0]) { - case ')': - stack.push(tok); - break; - case '(': - case 'CALL_START': - if (stack.length) { - stack.pop(); - } else if (tok[0] === '(') { - tok[0] = 'PARAM_START'; - return this; - } else { - return this; - } - } - } - return this; - }; - - Lexer.prototype.closeIndentation = function() { - return this.outdentToken(this.indent); - }; - - Lexer.prototype.balancedString = function(str, end) { - var i, letter, match, prev, stack, _ref3; - stack = [end]; - for (i = 1, _ref3 = str.length; 1 <= _ref3 ? i < _ref3 : i > _ref3; 1 <= _ref3 ? i++ : i--) { - switch (letter = str.charAt(i)) { - case '\\': - i++; - continue; - case end: - stack.pop(); - if (!stack.length) return str.slice(0, i + 1); - end = stack[stack.length - 1]; - continue; - } - if (end === '}' && (letter === '"' || letter === "'")) { - stack.push(end = letter); - } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) { - i += match[0].length - 1; - } else if (end === '}' && letter === '{') { - stack.push(end = '}'); - } else if (end === '"' && prev === '#' && letter === '{') { - stack.push(end = '}'); - } - prev = letter; - } - return this.error("missing " + (stack.pop()) + ", starting"); - }; - - Lexer.prototype.interpolateString = function(str, options) { - var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _len, _ref3, _ref4, _ref5; - if (options == null) options = {}; - heredoc = options.heredoc, regex = options.regex; - tokens = []; - pi = 0; - i = -1; - while (letter = str.charAt(i += 1)) { - if (letter === '\\') { - i += 1; - continue; - } - if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) { - continue; - } - if (pi < i) tokens.push(['NEOSTRING', str.slice(pi, i)]); - inner = expr.slice(1, -1); - if (inner.length) { - nested = new Lexer().tokenize(inner, { - line: this.line, - rewrite: false - }); - nested.pop(); - if (((_ref3 = nested[0]) != null ? _ref3[0] : void 0) === 'TERMINATOR') { - nested.shift(); - } - if (len = nested.length) { - if (len > 1) { - nested.unshift(['(', '(', this.line]); - nested.push([')', ')', this.line]); - } - tokens.push(['TOKENS', nested]); - } - } - i += expr.length; - pi = i + 1; - } - if ((i > pi && pi < str.length)) tokens.push(['NEOSTRING', str.slice(pi)]); - if (regex) return tokens; - if (!tokens.length) return this.token('STRING', '""'); - if (tokens[0][0] !== 'NEOSTRING') tokens.unshift(['', '']); - if (interpolated = tokens.length > 1) this.token('(', '('); - for (i = 0, _len = tokens.length; i < _len; i++) { - _ref4 = tokens[i], tag = _ref4[0], value = _ref4[1]; - if (i) this.token('+', '+'); - if (tag === 'TOKENS') { - (_ref5 = this.tokens).push.apply(_ref5, value); - } else { - this.token('STRING', this.makeString(value, '"', heredoc)); - } - } - if (interpolated) this.token(')', ')'); - return tokens; - }; - - Lexer.prototype.pair = function(tag) { - var size, wanted; - if (tag !== (wanted = last(this.ends))) { - if ('OUTDENT' !== wanted) this.error("unmatched " + tag); - this.indent -= size = last(this.indents); - this.outdentToken(size, true); - return this.pair(tag); - } - return this.ends.pop(); - }; - - Lexer.prototype.token = function(tag, value) { - return this.tokens.push([tag, value, this.line]); - }; - - Lexer.prototype.tag = function(index, tag) { - var tok; - return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]); - }; - - Lexer.prototype.value = function(index, val) { - var tok; - return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]); - }; - - Lexer.prototype.unfinished = function() { - var _ref3; - return LINE_CONTINUER.test(this.chunk) || ((_ref3 = this.tag()) === '\\' || _ref3 === '.' || _ref3 === '?.' || _ref3 === 'UNARY' || _ref3 === 'MATH' || _ref3 === '+' || _ref3 === '-' || _ref3 === 'SHIFT' || _ref3 === 'RELATION' || _ref3 === 'COMPARE' || _ref3 === 'LOGIC' || _ref3 === 'COMPOUND_ASSIGN' || _ref3 === 'THROW' || _ref3 === 'EXTENDS'); - }; - - Lexer.prototype.escapeLines = function(str, heredoc) { - return str.replace(MULTILINER, heredoc ? '\\n' : ''); - }; - - Lexer.prototype.makeString = function(body, quote, heredoc) { - if (!body) return quote + quote; - body = body.replace(/\\([\s\S])/g, function(match, contents) { - if (contents === '\n' || contents === quote) { - return contents; - } else { - return match; - } - }); - body = body.replace(RegExp("" + quote, "g"), '\\$&'); - return quote + this.escapeLines(body, heredoc) + quote; - }; - - Lexer.prototype.error = function(message) { - throw SyntaxError("" + message + " on line " + (this.line + 1)); - }; - - return Lexer; - - })(); - - JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super']; - - COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']; - - COFFEE_ALIAS_MAP = { - and: '&&', - or: '||', - is: '==', - isnt: '!=', - not: '!', - yes: 'true', - no: 'false', - on: 'true', - off: 'false' - }; - - COFFEE_ALIASES = (function() { - var _results; - _results = []; - for (key in COFFEE_ALIAS_MAP) { - _results.push(key); - } - return _results; - })(); - - COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES); - - RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf']; - - JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED); - - exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS); - - IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/; - - NUMBER = /^0x[\da-f]+|^0b[01]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; - - HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/; - - OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/; - - WHITESPACE = /^[^\n\S]+/; - - COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/; - - CODE = /^[-=]>/; - - MULTI_DENT = /^(?:\n[^\n\S]*)+/; - - SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/; - - JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/; - - REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/; - - HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/; - - HEREGEX_OMIT = /\s+(?:#.*)?/g; - - MULTILINER = /\n/g; - - HEREDOC_INDENT = /\n+([^\n\S]*)/g; - - HEREDOC_ILLEGAL = /\*\//; - - LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/; - - TRAILING_SPACES = /\s+$/; - - COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']; - - UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']; - - LOGIC = ['&&', '||', '&', '|', '^']; - - SHIFT = ['<<', '>>', '>>>']; - - COMPARE = ['==', '!=', '<', '>', '<=', '>=']; - - MATH = ['*', '/', '%']; - - RELATION = ['IN', 'OF', 'INSTANCEOF']; - - BOOL = ['TRUE', 'FALSE', 'NULL', 'UNDEFINED']; - - NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']']; - - NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING'); - - CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']; - - INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL'); - - LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']; - -}).call(this); - -};require['./parser'] = new function() { - var exports = this; - /* Jison generated parser */ -var parser = (function(){ -var parser = {trace: function trace() { }, -yy: {}, -symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Comment":11,"STATEMENT":12,"Value":13,"Invocation":14,"Code":15,"Operation":16,"Assign":17,"If":18,"Try":19,"While":20,"For":21,"Switch":22,"Class":23,"Throw":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"DEBUGGER":35,"BOOL":36,"Assignable":37,"=":38,"AssignObj":39,"ObjAssignable":40,":":41,"ThisProperty":42,"RETURN":43,"HERECOMMENT":44,"PARAM_START":45,"ParamList":46,"PARAM_END":47,"FuncGlyph":48,"->":49,"=>":50,"OptComma":51,",":52,"Param":53,"ParamVar":54,"...":55,"Array":56,"Object":57,"Splat":58,"SimpleAssignable":59,"Accessor":60,"Parenthetical":61,"Range":62,"This":63,".":64,"?.":65,"::":66,"Index":67,"INDEX_START":68,"IndexValue":69,"INDEX_END":70,"INDEX_SOAK":71,"Slice":72,"{":73,"AssignList":74,"}":75,"CLASS":76,"EXTENDS":77,"OptFuncExist":78,"Arguments":79,"SUPER":80,"FUNC_EXIST":81,"CALL_START":82,"CALL_END":83,"ArgList":84,"THIS":85,"@":86,"[":87,"]":88,"RangeDots":89,"..":90,"Arg":91,"SimpleArgs":92,"TRY":93,"Catch":94,"FINALLY":95,"CATCH":96,"THROW":97,"(":98,")":99,"WhileSource":100,"WHILE":101,"WHEN":102,"UNTIL":103,"Loop":104,"LOOP":105,"ForBody":106,"FOR":107,"ForStart":108,"ForSource":109,"ForVariables":110,"OWN":111,"ForValue":112,"FORIN":113,"FOROF":114,"BY":115,"SWITCH":116,"Whens":117,"ELSE":118,"When":119,"LEADING_WHEN":120,"IfBlock":121,"IF":122,"POST_IF":123,"UNARY":124,"-":125,"+":126,"--":127,"++":128,"?":129,"MATH":130,"SHIFT":131,"COMPARE":132,"LOGIC":133,"RELATION":134,"COMPOUND_ASSIGN":135,"$accept":0,"$end":1}, -terminals_: {2:"error",6:"TERMINATOR",12:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"BOOL",38:"=",41:":",43:"RETURN",44:"HERECOMMENT",45:"PARAM_START",47:"PARAM_END",49:"->",50:"=>",52:",",55:"...",64:".",65:"?.",66:"::",68:"INDEX_START",70:"INDEX_END",71:"INDEX_SOAK",73:"{",75:"}",76:"CLASS",77:"EXTENDS",80:"SUPER",81:"FUNC_EXIST",82:"CALL_START",83:"CALL_END",85:"THIS",86:"@",87:"[",88:"]",90:"..",93:"TRY",95:"FINALLY",96:"CATCH",97:"THROW",98:"(",99:")",101:"WHILE",102:"WHEN",103:"UNTIL",105:"LOOP",107:"FOR",111:"OWN",113:"FORIN",114:"FOROF",115:"BY",116:"SWITCH",118:"ELSE",120:"LEADING_WHEN",122:"IF",123:"POST_IF",124:"UNARY",125:"-",126:"+",127:"--",128:"++",129:"?",130:"MATH",131:"SHIFT",132:"COMPARE",133:"LOGIC",134:"RELATION",135:"COMPOUND_ASSIGN"}, -productions_: [0,[3,0],[3,1],[3,2],[4,1],[4,3],[4,2],[7,1],[7,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[5,2],[5,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[17,3],[17,4],[17,5],[39,1],[39,3],[39,5],[39,1],[40,1],[40,1],[40,1],[10,2],[10,1],[11,1],[15,5],[15,2],[48,1],[48,1],[51,0],[51,1],[46,0],[46,1],[46,3],[53,1],[53,2],[53,3],[54,1],[54,1],[54,1],[54,1],[58,2],[59,1],[59,2],[59,2],[59,1],[37,1],[37,1],[37,1],[13,1],[13,1],[13,1],[13,1],[13,1],[60,2],[60,2],[60,2],[60,1],[60,1],[67,3],[67,2],[69,1],[69,1],[57,4],[74,0],[74,1],[74,3],[74,4],[74,6],[23,1],[23,2],[23,3],[23,4],[23,2],[23,3],[23,4],[23,5],[14,3],[14,3],[14,1],[14,2],[78,0],[78,1],[79,2],[79,4],[63,1],[63,1],[42,2],[56,2],[56,4],[89,1],[89,1],[62,5],[72,3],[72,2],[72,2],[84,1],[84,3],[84,4],[84,4],[84,6],[91,1],[91,1],[92,1],[92,3],[19,2],[19,3],[19,4],[19,5],[94,3],[24,2],[61,3],[61,5],[100,2],[100,4],[100,2],[100,4],[20,2],[20,2],[20,2],[20,1],[104,2],[104,2],[21,2],[21,2],[21,2],[106,2],[106,2],[108,2],[108,3],[112,1],[112,1],[112,1],[110,1],[110,3],[109,2],[109,2],[109,4],[109,4],[109,4],[109,6],[109,6],[22,5],[22,7],[22,4],[22,6],[117,1],[117,2],[119,3],[119,4],[121,3],[121,5],[18,1],[18,3],[18,3],[18,3],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,5],[16,3]], -performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { - -var $0 = $$.length - 1; -switch (yystate) { -case 1:return this.$ = new yy.Block; -break; -case 2:return this.$ = $$[$0]; -break; -case 3:return this.$ = $$[$0-1]; -break; -case 4:this.$ = yy.Block.wrap([$$[$0]]); -break; -case 5:this.$ = $$[$0-2].push($$[$0]); -break; -case 6:this.$ = $$[$0-1]; -break; -case 7:this.$ = $$[$0]; -break; -case 8:this.$ = $$[$0]; -break; -case 9:this.$ = $$[$0]; -break; -case 10:this.$ = $$[$0]; -break; -case 11:this.$ = new yy.Literal($$[$0]); -break; -case 12:this.$ = $$[$0]; -break; -case 13:this.$ = $$[$0]; -break; -case 14:this.$ = $$[$0]; -break; -case 15:this.$ = $$[$0]; -break; -case 16:this.$ = $$[$0]; -break; -case 17:this.$ = $$[$0]; -break; -case 18:this.$ = $$[$0]; -break; -case 19:this.$ = $$[$0]; -break; -case 20:this.$ = $$[$0]; -break; -case 21:this.$ = $$[$0]; -break; -case 22:this.$ = $$[$0]; -break; -case 23:this.$ = $$[$0]; -break; -case 24:this.$ = new yy.Block; -break; -case 25:this.$ = $$[$0-1]; -break; -case 26:this.$ = new yy.Literal($$[$0]); -break; -case 27:this.$ = new yy.Literal($$[$0]); -break; -case 28:this.$ = new yy.Literal($$[$0]); -break; -case 29:this.$ = $$[$0]; -break; -case 30:this.$ = new yy.Literal($$[$0]); -break; -case 31:this.$ = new yy.Literal($$[$0]); -break; -case 32:this.$ = new yy.Literal($$[$0]); -break; -case 33:this.$ = (function () { - var val; - val = new yy.Literal($$[$0]); - if ($$[$0] === 'undefined') val.isUndefined = true; - return val; - }()); -break; -case 34:this.$ = new yy.Assign($$[$0-2], $$[$0]); -break; -case 35:this.$ = new yy.Assign($$[$0-3], $$[$0]); -break; -case 36:this.$ = new yy.Assign($$[$0-4], $$[$0-1]); -break; -case 37:this.$ = new yy.Value($$[$0]); -break; -case 38:this.$ = new yy.Assign(new yy.Value($$[$0-2]), $$[$0], 'object'); -break; -case 39:this.$ = new yy.Assign(new yy.Value($$[$0-4]), $$[$0-1], 'object'); -break; -case 40:this.$ = $$[$0]; -break; -case 41:this.$ = $$[$0]; -break; -case 42:this.$ = $$[$0]; -break; -case 43:this.$ = $$[$0]; -break; -case 44:this.$ = new yy.Return($$[$0]); -break; -case 45:this.$ = new yy.Return; -break; -case 46:this.$ = new yy.Comment($$[$0]); -break; -case 47:this.$ = new yy.Code($$[$0-3], $$[$0], $$[$0-1]); -break; -case 48:this.$ = new yy.Code([], $$[$0], $$[$0-1]); -break; -case 49:this.$ = 'func'; -break; -case 50:this.$ = 'boundfunc'; -break; -case 51:this.$ = $$[$0]; -break; -case 52:this.$ = $$[$0]; -break; -case 53:this.$ = []; -break; -case 54:this.$ = [$$[$0]]; -break; -case 55:this.$ = $$[$0-2].concat($$[$0]); -break; -case 56:this.$ = new yy.Param($$[$0]); -break; -case 57:this.$ = new yy.Param($$[$0-1], null, true); -break; -case 58:this.$ = new yy.Param($$[$0-2], $$[$0]); -break; -case 59:this.$ = $$[$0]; -break; -case 60:this.$ = $$[$0]; -break; -case 61:this.$ = $$[$0]; -break; -case 62:this.$ = $$[$0]; -break; -case 63:this.$ = new yy.Splat($$[$0-1]); -break; -case 64:this.$ = new yy.Value($$[$0]); -break; -case 65:this.$ = $$[$0-1].add($$[$0]); -break; -case 66:this.$ = new yy.Value($$[$0-1], [].concat($$[$0])); -break; -case 67:this.$ = $$[$0]; -break; -case 68:this.$ = $$[$0]; -break; -case 69:this.$ = new yy.Value($$[$0]); -break; -case 70:this.$ = new yy.Value($$[$0]); -break; -case 71:this.$ = $$[$0]; -break; -case 72:this.$ = new yy.Value($$[$0]); -break; -case 73:this.$ = new yy.Value($$[$0]); -break; -case 74:this.$ = new yy.Value($$[$0]); -break; -case 75:this.$ = $$[$0]; -break; -case 76:this.$ = new yy.Access($$[$0]); -break; -case 77:this.$ = new yy.Access($$[$0], 'soak'); -break; -case 78:this.$ = [new yy.Access(new yy.Literal('prototype')), new yy.Access($$[$0])]; -break; -case 79:this.$ = new yy.Access(new yy.Literal('prototype')); -break; -case 80:this.$ = $$[$0]; -break; -case 81:this.$ = $$[$0-1]; -break; -case 82:this.$ = yy.extend($$[$0], { - soak: true - }); -break; -case 83:this.$ = new yy.Index($$[$0]); -break; -case 84:this.$ = new yy.Slice($$[$0]); -break; -case 85:this.$ = new yy.Obj($$[$0-2], $$[$0-3].generated); -break; -case 86:this.$ = []; -break; -case 87:this.$ = [$$[$0]]; -break; -case 88:this.$ = $$[$0-2].concat($$[$0]); -break; -case 89:this.$ = $$[$0-3].concat($$[$0]); -break; -case 90:this.$ = $$[$0-5].concat($$[$0-2]); -break; -case 91:this.$ = new yy.Class; -break; -case 92:this.$ = new yy.Class(null, null, $$[$0]); -break; -case 93:this.$ = new yy.Class(null, $$[$0]); -break; -case 94:this.$ = new yy.Class(null, $$[$0-1], $$[$0]); -break; -case 95:this.$ = new yy.Class($$[$0]); -break; -case 96:this.$ = new yy.Class($$[$0-1], null, $$[$0]); -break; -case 97:this.$ = new yy.Class($$[$0-2], $$[$0]); -break; -case 98:this.$ = new yy.Class($$[$0-3], $$[$0-1], $$[$0]); -break; -case 99:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]); -break; -case 100:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]); -break; -case 101:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]); -break; -case 102:this.$ = new yy.Call('super', $$[$0]); -break; -case 103:this.$ = false; -break; -case 104:this.$ = true; -break; -case 105:this.$ = []; -break; -case 106:this.$ = $$[$0-2]; -break; -case 107:this.$ = new yy.Value(new yy.Literal('this')); -break; -case 108:this.$ = new yy.Value(new yy.Literal('this')); -break; -case 109:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Access($$[$0])], 'this'); -break; -case 110:this.$ = new yy.Arr([]); -break; -case 111:this.$ = new yy.Arr($$[$0-2]); -break; -case 112:this.$ = 'inclusive'; -break; -case 113:this.$ = 'exclusive'; -break; -case 114:this.$ = new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]); -break; -case 115:this.$ = new yy.Range($$[$0-2], $$[$0], $$[$0-1]); -break; -case 116:this.$ = new yy.Range($$[$0-1], null, $$[$0]); -break; -case 117:this.$ = new yy.Range(null, $$[$0], $$[$0-1]); -break; -case 118:this.$ = [$$[$0]]; -break; -case 119:this.$ = $$[$0-2].concat($$[$0]); -break; -case 120:this.$ = $$[$0-3].concat($$[$0]); -break; -case 121:this.$ = $$[$0-2]; -break; -case 122:this.$ = $$[$0-5].concat($$[$0-2]); -break; -case 123:this.$ = $$[$0]; -break; -case 124:this.$ = $$[$0]; -break; -case 125:this.$ = $$[$0]; -break; -case 126:this.$ = [].concat($$[$0-2], $$[$0]); -break; -case 127:this.$ = new yy.Try($$[$0]); -break; -case 128:this.$ = new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]); -break; -case 129:this.$ = new yy.Try($$[$0-2], null, null, $$[$0]); -break; -case 130:this.$ = new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]); -break; -case 131:this.$ = [$$[$0-1], $$[$0]]; -break; -case 132:this.$ = new yy.Throw($$[$0]); -break; -case 133:this.$ = new yy.Parens($$[$0-1]); -break; -case 134:this.$ = new yy.Parens($$[$0-2]); -break; -case 135:this.$ = new yy.While($$[$0]); -break; -case 136:this.$ = new yy.While($$[$0-2], { - guard: $$[$0] - }); -break; -case 137:this.$ = new yy.While($$[$0], { - invert: true - }); -break; -case 138:this.$ = new yy.While($$[$0-2], { - invert: true, - guard: $$[$0] - }); -break; -case 139:this.$ = $$[$0-1].addBody($$[$0]); -break; -case 140:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]])); -break; -case 141:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]])); -break; -case 142:this.$ = $$[$0]; -break; -case 143:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]); -break; -case 144:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]])); -break; -case 145:this.$ = new yy.For($$[$0-1], $$[$0]); -break; -case 146:this.$ = new yy.For($$[$0-1], $$[$0]); -break; -case 147:this.$ = new yy.For($$[$0], $$[$0-1]); -break; -case 148:this.$ = { - source: new yy.Value($$[$0]) - }; -break; -case 149:this.$ = (function () { - $$[$0].own = $$[$0-1].own; - $$[$0].name = $$[$0-1][0]; - $$[$0].index = $$[$0-1][1]; - return $$[$0]; - }()); -break; -case 150:this.$ = $$[$0]; -break; -case 151:this.$ = (function () { - $$[$0].own = true; - return $$[$0]; - }()); -break; -case 152:this.$ = $$[$0]; -break; -case 153:this.$ = new yy.Value($$[$0]); -break; -case 154:this.$ = new yy.Value($$[$0]); -break; -case 155:this.$ = [$$[$0]]; -break; -case 156:this.$ = [$$[$0-2], $$[$0]]; -break; -case 157:this.$ = { - source: $$[$0] - }; -break; -case 158:this.$ = { - source: $$[$0], - object: true - }; -break; -case 159:this.$ = { - source: $$[$0-2], - guard: $$[$0] - }; -break; -case 160:this.$ = { - source: $$[$0-2], - guard: $$[$0], - object: true - }; -break; -case 161:this.$ = { - source: $$[$0-2], - step: $$[$0] - }; -break; -case 162:this.$ = { - source: $$[$0-4], - guard: $$[$0-2], - step: $$[$0] - }; -break; -case 163:this.$ = { - source: $$[$0-4], - step: $$[$0-2], - guard: $$[$0] - }; -break; -case 164:this.$ = new yy.Switch($$[$0-3], $$[$0-1]); -break; -case 165:this.$ = new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]); -break; -case 166:this.$ = new yy.Switch(null, $$[$0-1]); -break; -case 167:this.$ = new yy.Switch(null, $$[$0-3], $$[$0-1]); -break; -case 168:this.$ = $$[$0]; -break; -case 169:this.$ = $$[$0-1].concat($$[$0]); -break; -case 170:this.$ = [[$$[$0-1], $$[$0]]]; -break; -case 171:this.$ = [[$$[$0-2], $$[$0-1]]]; -break; -case 172:this.$ = new yy.If($$[$0-1], $$[$0], { - type: $$[$0-2] - }); -break; -case 173:this.$ = $$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], { - type: $$[$0-2] - })); -break; -case 174:this.$ = $$[$0]; -break; -case 175:this.$ = $$[$0-2].addElse($$[$0]); -break; -case 176:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), { - type: $$[$0-1], - statement: true - }); -break; -case 177:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), { - type: $$[$0-1], - statement: true - }); -break; -case 178:this.$ = new yy.Op($$[$0-1], $$[$0]); -break; -case 179:this.$ = new yy.Op('-', $$[$0]); -break; -case 180:this.$ = new yy.Op('+', $$[$0]); -break; -case 181:this.$ = new yy.Op('--', $$[$0]); -break; -case 182:this.$ = new yy.Op('++', $$[$0]); -break; -case 183:this.$ = new yy.Op('--', $$[$0-1], null, true); -break; -case 184:this.$ = new yy.Op('++', $$[$0-1], null, true); -break; -case 185:this.$ = new yy.Existence($$[$0-1]); -break; -case 186:this.$ = new yy.Op('+', $$[$0-2], $$[$0]); -break; -case 187:this.$ = new yy.Op('-', $$[$0-2], $$[$0]); -break; -case 188:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 189:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 190:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 191:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 192:this.$ = (function () { - if ($$[$0-1].charAt(0) === '!') { - return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert(); - } else { - return new yy.Op($$[$0-1], $$[$0-2], $$[$0]); - } - }()); -break; -case 193:this.$ = new yy.Assign($$[$0-2], $$[$0], $$[$0-1]); -break; -case 194:this.$ = new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]); -break; -case 195:this.$ = new yy.Extends($$[$0-2], $$[$0]); -break; -} -}, -table: [{1:[2,1],3:1,4:2,5:3,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[3]},{1:[2,2],6:[1,72]},{6:[1,73]},{1:[2,4],6:[2,4],26:[2,4],99:[2,4]},{4:75,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[1,74],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,7],6:[2,7],26:[2,7],99:[2,7],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,8],6:[2,8],26:[2,8],99:[2,8],100:88,101:[1,63],103:[1,64],106:89,107:[1,66],108:67,123:[1,87]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],47:[2,12],52:[2,12],55:[2,12],60:91,64:[1,93],65:[1,94],66:[1,95],67:96,68:[1,97],70:[2,12],71:[1,98],75:[2,12],78:90,81:[1,92],82:[2,103],83:[2,12],88:[2,12],90:[2,12],99:[2,12],101:[2,12],102:[2,12],103:[2,12],107:[2,12],115:[2,12],123:[2,12],125:[2,12],126:[2,12],129:[2,12],130:[2,12],131:[2,12],132:[2,12],133:[2,12],134:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],47:[2,13],52:[2,13],55:[2,13],60:100,64:[1,93],65:[1,94],66:[1,95],67:96,68:[1,97],70:[2,13],71:[1,98],75:[2,13],78:99,81:[1,92],82:[2,103],83:[2,13],88:[2,13],90:[2,13],99:[2,13],101:[2,13],102:[2,13],103:[2,13],107:[2,13],115:[2,13],123:[2,13],125:[2,13],126:[2,13],129:[2,13],130:[2,13],131:[2,13],132:[2,13],133:[2,13],134:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],47:[2,14],52:[2,14],55:[2,14],70:[2,14],75:[2,14],83:[2,14],88:[2,14],90:[2,14],99:[2,14],101:[2,14],102:[2,14],103:[2,14],107:[2,14],115:[2,14],123:[2,14],125:[2,14],126:[2,14],129:[2,14],130:[2,14],131:[2,14],132:[2,14],133:[2,14],134:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],47:[2,15],52:[2,15],55:[2,15],70:[2,15],75:[2,15],83:[2,15],88:[2,15],90:[2,15],99:[2,15],101:[2,15],102:[2,15],103:[2,15],107:[2,15],115:[2,15],123:[2,15],125:[2,15],126:[2,15],129:[2,15],130:[2,15],131:[2,15],132:[2,15],133:[2,15],134:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],47:[2,16],52:[2,16],55:[2,16],70:[2,16],75:[2,16],83:[2,16],88:[2,16],90:[2,16],99:[2,16],101:[2,16],102:[2,16],103:[2,16],107:[2,16],115:[2,16],123:[2,16],125:[2,16],126:[2,16],129:[2,16],130:[2,16],131:[2,16],132:[2,16],133:[2,16],134:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],47:[2,17],52:[2,17],55:[2,17],70:[2,17],75:[2,17],83:[2,17],88:[2,17],90:[2,17],99:[2,17],101:[2,17],102:[2,17],103:[2,17],107:[2,17],115:[2,17],123:[2,17],125:[2,17],126:[2,17],129:[2,17],130:[2,17],131:[2,17],132:[2,17],133:[2,17],134:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],47:[2,18],52:[2,18],55:[2,18],70:[2,18],75:[2,18],83:[2,18],88:[2,18],90:[2,18],99:[2,18],101:[2,18],102:[2,18],103:[2,18],107:[2,18],115:[2,18],123:[2,18],125:[2,18],126:[2,18],129:[2,18],130:[2,18],131:[2,18],132:[2,18],133:[2,18],134:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],47:[2,19],52:[2,19],55:[2,19],70:[2,19],75:[2,19],83:[2,19],88:[2,19],90:[2,19],99:[2,19],101:[2,19],102:[2,19],103:[2,19],107:[2,19],115:[2,19],123:[2,19],125:[2,19],126:[2,19],129:[2,19],130:[2,19],131:[2,19],132:[2,19],133:[2,19],134:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],47:[2,20],52:[2,20],55:[2,20],70:[2,20],75:[2,20],83:[2,20],88:[2,20],90:[2,20],99:[2,20],101:[2,20],102:[2,20],103:[2,20],107:[2,20],115:[2,20],123:[2,20],125:[2,20],126:[2,20],129:[2,20],130:[2,20],131:[2,20],132:[2,20],133:[2,20],134:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],47:[2,21],52:[2,21],55:[2,21],70:[2,21],75:[2,21],83:[2,21],88:[2,21],90:[2,21],99:[2,21],101:[2,21],102:[2,21],103:[2,21],107:[2,21],115:[2,21],123:[2,21],125:[2,21],126:[2,21],129:[2,21],130:[2,21],131:[2,21],132:[2,21],133:[2,21],134:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],47:[2,22],52:[2,22],55:[2,22],70:[2,22],75:[2,22],83:[2,22],88:[2,22],90:[2,22],99:[2,22],101:[2,22],102:[2,22],103:[2,22],107:[2,22],115:[2,22],123:[2,22],125:[2,22],126:[2,22],129:[2,22],130:[2,22],131:[2,22],132:[2,22],133:[2,22],134:[2,22]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],47:[2,23],52:[2,23],55:[2,23],70:[2,23],75:[2,23],83:[2,23],88:[2,23],90:[2,23],99:[2,23],101:[2,23],102:[2,23],103:[2,23],107:[2,23],115:[2,23],123:[2,23],125:[2,23],126:[2,23],129:[2,23],130:[2,23],131:[2,23],132:[2,23],133:[2,23],134:[2,23]},{1:[2,9],6:[2,9],26:[2,9],99:[2,9],101:[2,9],103:[2,9],107:[2,9],123:[2,9]},{1:[2,10],6:[2,10],26:[2,10],99:[2,10],101:[2,10],103:[2,10],107:[2,10],123:[2,10]},{1:[2,11],6:[2,11],26:[2,11],99:[2,11],101:[2,11],103:[2,11],107:[2,11],123:[2,11]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],38:[1,101],47:[2,71],52:[2,71],55:[2,71],64:[2,71],65:[2,71],66:[2,71],68:[2,71],70:[2,71],71:[2,71],75:[2,71],81:[2,71],82:[2,71],83:[2,71],88:[2,71],90:[2,71],99:[2,71],101:[2,71],102:[2,71],103:[2,71],107:[2,71],115:[2,71],123:[2,71],125:[2,71],126:[2,71],129:[2,71],130:[2,71],131:[2,71],132:[2,71],133:[2,71],134:[2,71]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],47:[2,72],52:[2,72],55:[2,72],64:[2,72],65:[2,72],66:[2,72],68:[2,72],70:[2,72],71:[2,72],75:[2,72],81:[2,72],82:[2,72],83:[2,72],88:[2,72],90:[2,72],99:[2,72],101:[2,72],102:[2,72],103:[2,72],107:[2,72],115:[2,72],123:[2,72],125:[2,72],126:[2,72],129:[2,72],130:[2,72],131:[2,72],132:[2,72],133:[2,72],134:[2,72]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],47:[2,73],52:[2,73],55:[2,73],64:[2,73],65:[2,73],66:[2,73],68:[2,73],70:[2,73],71:[2,73],75:[2,73],81:[2,73],82:[2,73],83:[2,73],88:[2,73],90:[2,73],99:[2,73],101:[2,73],102:[2,73],103:[2,73],107:[2,73],115:[2,73],123:[2,73],125:[2,73],126:[2,73],129:[2,73],130:[2,73],131:[2,73],132:[2,73],133:[2,73],134:[2,73]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],47:[2,74],52:[2,74],55:[2,74],64:[2,74],65:[2,74],66:[2,74],68:[2,74],70:[2,74],71:[2,74],75:[2,74],81:[2,74],82:[2,74],83:[2,74],88:[2,74],90:[2,74],99:[2,74],101:[2,74],102:[2,74],103:[2,74],107:[2,74],115:[2,74],123:[2,74],125:[2,74],126:[2,74],129:[2,74],130:[2,74],131:[2,74],132:[2,74],133:[2,74],134:[2,74]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],47:[2,75],52:[2,75],55:[2,75],64:[2,75],65:[2,75],66:[2,75],68:[2,75],70:[2,75],71:[2,75],75:[2,75],81:[2,75],82:[2,75],83:[2,75],88:[2,75],90:[2,75],99:[2,75],101:[2,75],102:[2,75],103:[2,75],107:[2,75],115:[2,75],123:[2,75],125:[2,75],126:[2,75],129:[2,75],130:[2,75],131:[2,75],132:[2,75],133:[2,75],134:[2,75]},{1:[2,101],6:[2,101],25:[2,101],26:[2,101],47:[2,101],52:[2,101],55:[2,101],64:[2,101],65:[2,101],66:[2,101],68:[2,101],70:[2,101],71:[2,101],75:[2,101],79:102,81:[2,101],82:[1,103],83:[2,101],88:[2,101],90:[2,101],99:[2,101],101:[2,101],102:[2,101],103:[2,101],107:[2,101],115:[2,101],123:[2,101],125:[2,101],126:[2,101],129:[2,101],130:[2,101],131:[2,101],132:[2,101],133:[2,101],134:[2,101]},{27:107,28:[1,71],42:108,46:104,47:[2,53],52:[2,53],53:105,54:106,56:109,57:110,73:[1,68],86:[1,111],87:[1,112]},{5:113,25:[1,5]},{8:114,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:116,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:117,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{13:119,14:120,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:121,42:61,56:47,57:48,59:118,61:25,62:26,63:27,73:[1,68],80:[1,28],85:[1,56],86:[1,57],87:[1,55],98:[1,54]},{13:119,14:120,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:121,42:61,56:47,57:48,59:122,61:25,62:26,63:27,73:[1,68],80:[1,28],85:[1,56],86:[1,57],87:[1,55],98:[1,54]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],38:[2,68],47:[2,68],52:[2,68],55:[2,68],64:[2,68],65:[2,68],66:[2,68],68:[2,68],70:[2,68],71:[2,68],75:[2,68],77:[1,126],81:[2,68],82:[2,68],83:[2,68],88:[2,68],90:[2,68],99:[2,68],101:[2,68],102:[2,68],103:[2,68],107:[2,68],115:[2,68],123:[2,68],125:[2,68],126:[2,68],127:[1,123],128:[1,124],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[1,125]},{1:[2,174],6:[2,174],25:[2,174],26:[2,174],47:[2,174],52:[2,174],55:[2,174],70:[2,174],75:[2,174],83:[2,174],88:[2,174],90:[2,174],99:[2,174],101:[2,174],102:[2,174],103:[2,174],107:[2,174],115:[2,174],118:[1,127],123:[2,174],125:[2,174],126:[2,174],129:[2,174],130:[2,174],131:[2,174],132:[2,174],133:[2,174],134:[2,174]},{5:128,25:[1,5]},{5:129,25:[1,5]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],47:[2,142],52:[2,142],55:[2,142],70:[2,142],75:[2,142],83:[2,142],88:[2,142],90:[2,142],99:[2,142],101:[2,142],102:[2,142],103:[2,142],107:[2,142],115:[2,142],123:[2,142],125:[2,142],126:[2,142],129:[2,142],130:[2,142],131:[2,142],132:[2,142],133:[2,142],134:[2,142]},{5:130,25:[1,5]},{8:131,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,132],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,91],5:133,6:[2,91],13:119,14:120,25:[1,5],26:[2,91],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:121,42:61,47:[2,91],52:[2,91],55:[2,91],56:47,57:48,59:135,61:25,62:26,63:27,70:[2,91],73:[1,68],75:[2,91],77:[1,134],80:[1,28],83:[2,91],85:[1,56],86:[1,57],87:[1,55],88:[2,91],90:[2,91],98:[1,54],99:[2,91],101:[2,91],102:[2,91],103:[2,91],107:[2,91],115:[2,91],123:[2,91],125:[2,91],126:[2,91],129:[2,91],130:[2,91],131:[2,91],132:[2,91],133:[2,91],134:[2,91]},{8:136,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,45],6:[2,45],8:137,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,45],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],99:[2,45],100:39,101:[2,45],103:[2,45],104:40,105:[1,65],106:41,107:[2,45],108:67,116:[1,42],121:37,122:[1,62],123:[2,45],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,46],6:[2,46],25:[2,46],26:[2,46],52:[2,46],75:[2,46],99:[2,46],101:[2,46],103:[2,46],107:[2,46],123:[2,46]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],38:[2,69],47:[2,69],52:[2,69],55:[2,69],64:[2,69],65:[2,69],66:[2,69],68:[2,69],70:[2,69],71:[2,69],75:[2,69],81:[2,69],82:[2,69],83:[2,69],88:[2,69],90:[2,69],99:[2,69],101:[2,69],102:[2,69],103:[2,69],107:[2,69],115:[2,69],123:[2,69],125:[2,69],126:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],38:[2,70],47:[2,70],52:[2,70],55:[2,70],64:[2,70],65:[2,70],66:[2,70],68:[2,70],70:[2,70],71:[2,70],75:[2,70],81:[2,70],82:[2,70],83:[2,70],88:[2,70],90:[2,70],99:[2,70],101:[2,70],102:[2,70],103:[2,70],107:[2,70],115:[2,70],123:[2,70],125:[2,70],126:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],47:[2,29],52:[2,29],55:[2,29],64:[2,29],65:[2,29],66:[2,29],68:[2,29],70:[2,29],71:[2,29],75:[2,29],81:[2,29],82:[2,29],83:[2,29],88:[2,29],90:[2,29],99:[2,29],101:[2,29],102:[2,29],103:[2,29],107:[2,29],115:[2,29],123:[2,29],125:[2,29],126:[2,29],129:[2,29],130:[2,29],131:[2,29],132:[2,29],133:[2,29],134:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],47:[2,30],52:[2,30],55:[2,30],64:[2,30],65:[2,30],66:[2,30],68:[2,30],70:[2,30],71:[2,30],75:[2,30],81:[2,30],82:[2,30],83:[2,30],88:[2,30],90:[2,30],99:[2,30],101:[2,30],102:[2,30],103:[2,30],107:[2,30],115:[2,30],123:[2,30],125:[2,30],126:[2,30],129:[2,30],130:[2,30],131:[2,30],132:[2,30],133:[2,30],134:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],47:[2,31],52:[2,31],55:[2,31],64:[2,31],65:[2,31],66:[2,31],68:[2,31],70:[2,31],71:[2,31],75:[2,31],81:[2,31],82:[2,31],83:[2,31],88:[2,31],90:[2,31],99:[2,31],101:[2,31],102:[2,31],103:[2,31],107:[2,31],115:[2,31],123:[2,31],125:[2,31],126:[2,31],129:[2,31],130:[2,31],131:[2,31],132:[2,31],133:[2,31],134:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],47:[2,32],52:[2,32],55:[2,32],64:[2,32],65:[2,32],66:[2,32],68:[2,32],70:[2,32],71:[2,32],75:[2,32],81:[2,32],82:[2,32],83:[2,32],88:[2,32],90:[2,32],99:[2,32],101:[2,32],102:[2,32],103:[2,32],107:[2,32],115:[2,32],123:[2,32],125:[2,32],126:[2,32],129:[2,32],130:[2,32],131:[2,32],132:[2,32],133:[2,32],134:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],47:[2,33],52:[2,33],55:[2,33],64:[2,33],65:[2,33],66:[2,33],68:[2,33],70:[2,33],71:[2,33],75:[2,33],81:[2,33],82:[2,33],83:[2,33],88:[2,33],90:[2,33],99:[2,33],101:[2,33],102:[2,33],103:[2,33],107:[2,33],115:[2,33],123:[2,33],125:[2,33],126:[2,33],129:[2,33],130:[2,33],131:[2,33],132:[2,33],133:[2,33],134:[2,33]},{4:138,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,139],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:140,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,144],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],84:142,85:[1,56],86:[1,57],87:[1,55],88:[1,141],91:143,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,107],6:[2,107],25:[2,107],26:[2,107],47:[2,107],52:[2,107],55:[2,107],64:[2,107],65:[2,107],66:[2,107],68:[2,107],70:[2,107],71:[2,107],75:[2,107],81:[2,107],82:[2,107],83:[2,107],88:[2,107],90:[2,107],99:[2,107],101:[2,107],102:[2,107],103:[2,107],107:[2,107],115:[2,107],123:[2,107],125:[2,107],126:[2,107],129:[2,107],130:[2,107],131:[2,107],132:[2,107],133:[2,107],134:[2,107]},{1:[2,108],6:[2,108],25:[2,108],26:[2,108],27:146,28:[1,71],47:[2,108],52:[2,108],55:[2,108],64:[2,108],65:[2,108],66:[2,108],68:[2,108],70:[2,108],71:[2,108],75:[2,108],81:[2,108],82:[2,108],83:[2,108],88:[2,108],90:[2,108],99:[2,108],101:[2,108],102:[2,108],103:[2,108],107:[2,108],115:[2,108],123:[2,108],125:[2,108],126:[2,108],129:[2,108],130:[2,108],131:[2,108],132:[2,108],133:[2,108],134:[2,108]},{25:[2,49]},{25:[2,50]},{1:[2,64],6:[2,64],25:[2,64],26:[2,64],38:[2,64],47:[2,64],52:[2,64],55:[2,64],64:[2,64],65:[2,64],66:[2,64],68:[2,64],70:[2,64],71:[2,64],75:[2,64],77:[2,64],81:[2,64],82:[2,64],83:[2,64],88:[2,64],90:[2,64],99:[2,64],101:[2,64],102:[2,64],103:[2,64],107:[2,64],115:[2,64],123:[2,64],125:[2,64],126:[2,64],127:[2,64],128:[2,64],129:[2,64],130:[2,64],131:[2,64],132:[2,64],133:[2,64],134:[2,64],135:[2,64]},{1:[2,67],6:[2,67],25:[2,67],26:[2,67],38:[2,67],47:[2,67],52:[2,67],55:[2,67],64:[2,67],65:[2,67],66:[2,67],68:[2,67],70:[2,67],71:[2,67],75:[2,67],77:[2,67],81:[2,67],82:[2,67],83:[2,67],88:[2,67],90:[2,67],99:[2,67],101:[2,67],102:[2,67],103:[2,67],107:[2,67],115:[2,67],123:[2,67],125:[2,67],126:[2,67],127:[2,67],128:[2,67],129:[2,67],130:[2,67],131:[2,67],132:[2,67],133:[2,67],134:[2,67],135:[2,67]},{8:147,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:148,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:149,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{5:150,8:151,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{27:156,28:[1,71],56:157,57:158,62:152,73:[1,68],87:[1,55],110:153,111:[1,154],112:155},{109:159,113:[1,160],114:[1,161]},{6:[2,86],11:165,25:[2,86],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],39:163,40:164,42:168,44:[1,46],52:[2,86],74:162,75:[2,86],86:[1,111]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],41:[2,27],47:[2,27],52:[2,27],55:[2,27],64:[2,27],65:[2,27],66:[2,27],68:[2,27],70:[2,27],71:[2,27],75:[2,27],81:[2,27],82:[2,27],83:[2,27],88:[2,27],90:[2,27],99:[2,27],101:[2,27],102:[2,27],103:[2,27],107:[2,27],115:[2,27],123:[2,27],125:[2,27],126:[2,27],129:[2,27],130:[2,27],131:[2,27],132:[2,27],133:[2,27],134:[2,27]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],41:[2,28],47:[2,28],52:[2,28],55:[2,28],64:[2,28],65:[2,28],66:[2,28],68:[2,28],70:[2,28],71:[2,28],75:[2,28],81:[2,28],82:[2,28],83:[2,28],88:[2,28],90:[2,28],99:[2,28],101:[2,28],102:[2,28],103:[2,28],107:[2,28],115:[2,28],123:[2,28],125:[2,28],126:[2,28],129:[2,28],130:[2,28],131:[2,28],132:[2,28],133:[2,28],134:[2,28]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],38:[2,26],41:[2,26],47:[2,26],52:[2,26],55:[2,26],64:[2,26],65:[2,26],66:[2,26],68:[2,26],70:[2,26],71:[2,26],75:[2,26],77:[2,26],81:[2,26],82:[2,26],83:[2,26],88:[2,26],90:[2,26],99:[2,26],101:[2,26],102:[2,26],103:[2,26],107:[2,26],113:[2,26],114:[2,26],115:[2,26],123:[2,26],125:[2,26],126:[2,26],127:[2,26],128:[2,26],129:[2,26],130:[2,26],131:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26]},{1:[2,6],6:[2,6],7:169,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,6],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],99:[2,6],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,3]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],47:[2,24],52:[2,24],55:[2,24],70:[2,24],75:[2,24],83:[2,24],88:[2,24],90:[2,24],95:[2,24],96:[2,24],99:[2,24],101:[2,24],102:[2,24],103:[2,24],107:[2,24],115:[2,24],118:[2,24],120:[2,24],123:[2,24],125:[2,24],126:[2,24],129:[2,24],130:[2,24],131:[2,24],132:[2,24],133:[2,24],134:[2,24]},{6:[1,72],26:[1,170]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],47:[2,185],52:[2,185],55:[2,185],70:[2,185],75:[2,185],83:[2,185],88:[2,185],90:[2,185],99:[2,185],101:[2,185],102:[2,185],103:[2,185],107:[2,185],115:[2,185],123:[2,185],125:[2,185],126:[2,185],129:[2,185],130:[2,185],131:[2,185],132:[2,185],133:[2,185],134:[2,185]},{8:171,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:172,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:173,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:174,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:175,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:176,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:177,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:178,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],47:[2,141],52:[2,141],55:[2,141],70:[2,141],75:[2,141],83:[2,141],88:[2,141],90:[2,141],99:[2,141],101:[2,141],102:[2,141],103:[2,141],107:[2,141],115:[2,141],123:[2,141],125:[2,141],126:[2,141],129:[2,141],130:[2,141],131:[2,141],132:[2,141],133:[2,141],134:[2,141]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],47:[2,146],52:[2,146],55:[2,146],70:[2,146],75:[2,146],83:[2,146],88:[2,146],90:[2,146],99:[2,146],101:[2,146],102:[2,146],103:[2,146],107:[2,146],115:[2,146],123:[2,146],125:[2,146],126:[2,146],129:[2,146],130:[2,146],131:[2,146],132:[2,146],133:[2,146],134:[2,146]},{8:179,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],47:[2,140],52:[2,140],55:[2,140],70:[2,140],75:[2,140],83:[2,140],88:[2,140],90:[2,140],99:[2,140],101:[2,140],102:[2,140],103:[2,140],107:[2,140],115:[2,140],123:[2,140],125:[2,140],126:[2,140],129:[2,140],130:[2,140],131:[2,140],132:[2,140],133:[2,140],134:[2,140]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],47:[2,145],52:[2,145],55:[2,145],70:[2,145],75:[2,145],83:[2,145],88:[2,145],90:[2,145],99:[2,145],101:[2,145],102:[2,145],103:[2,145],107:[2,145],115:[2,145],123:[2,145],125:[2,145],126:[2,145],129:[2,145],130:[2,145],131:[2,145],132:[2,145],133:[2,145],134:[2,145]},{79:180,82:[1,103]},{1:[2,65],6:[2,65],25:[2,65],26:[2,65],38:[2,65],47:[2,65],52:[2,65],55:[2,65],64:[2,65],65:[2,65],66:[2,65],68:[2,65],70:[2,65],71:[2,65],75:[2,65],77:[2,65],81:[2,65],82:[2,65],83:[2,65],88:[2,65],90:[2,65],99:[2,65],101:[2,65],102:[2,65],103:[2,65],107:[2,65],115:[2,65],123:[2,65],125:[2,65],126:[2,65],127:[2,65],128:[2,65],129:[2,65],130:[2,65],131:[2,65],132:[2,65],133:[2,65],134:[2,65],135:[2,65]},{82:[2,104]},{27:181,28:[1,71]},{27:182,28:[1,71]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],27:183,28:[1,71],38:[2,79],47:[2,79],52:[2,79],55:[2,79],64:[2,79],65:[2,79],66:[2,79],68:[2,79],70:[2,79],71:[2,79],75:[2,79],77:[2,79],81:[2,79],82:[2,79],83:[2,79],88:[2,79],90:[2,79],99:[2,79],101:[2,79],102:[2,79],103:[2,79],107:[2,79],115:[2,79],123:[2,79],125:[2,79],126:[2,79],127:[2,79],128:[2,79],129:[2,79],130:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],38:[2,80],47:[2,80],52:[2,80],55:[2,80],64:[2,80],65:[2,80],66:[2,80],68:[2,80],70:[2,80],71:[2,80],75:[2,80],77:[2,80],81:[2,80],82:[2,80],83:[2,80],88:[2,80],90:[2,80],99:[2,80],101:[2,80],102:[2,80],103:[2,80],107:[2,80],115:[2,80],123:[2,80],125:[2,80],126:[2,80],127:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80]},{8:185,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],55:[1,189],56:47,57:48,59:36,61:25,62:26,63:27,69:184,72:186,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],89:187,90:[1,188],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{67:190,68:[1,97],71:[1,98]},{79:191,82:[1,103]},{1:[2,66],6:[2,66],25:[2,66],26:[2,66],38:[2,66],47:[2,66],52:[2,66],55:[2,66],64:[2,66],65:[2,66],66:[2,66],68:[2,66],70:[2,66],71:[2,66],75:[2,66],77:[2,66],81:[2,66],82:[2,66],83:[2,66],88:[2,66],90:[2,66],99:[2,66],101:[2,66],102:[2,66],103:[2,66],107:[2,66],115:[2,66],123:[2,66],125:[2,66],126:[2,66],127:[2,66],128:[2,66],129:[2,66],130:[2,66],131:[2,66],132:[2,66],133:[2,66],134:[2,66],135:[2,66]},{6:[1,193],8:192,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,194],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,102],6:[2,102],25:[2,102],26:[2,102],47:[2,102],52:[2,102],55:[2,102],64:[2,102],65:[2,102],66:[2,102],68:[2,102],70:[2,102],71:[2,102],75:[2,102],81:[2,102],82:[2,102],83:[2,102],88:[2,102],90:[2,102],99:[2,102],101:[2,102],102:[2,102],103:[2,102],107:[2,102],115:[2,102],123:[2,102],125:[2,102],126:[2,102],129:[2,102],130:[2,102],131:[2,102],132:[2,102],133:[2,102],134:[2,102]},{8:197,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,144],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],83:[1,195],84:196,85:[1,56],86:[1,57],87:[1,55],91:143,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{47:[1,198],52:[1,199]},{47:[2,54],52:[2,54]},{38:[1,201],47:[2,56],52:[2,56],55:[1,200]},{38:[2,59],47:[2,59],52:[2,59],55:[2,59]},{38:[2,60],47:[2,60],52:[2,60],55:[2,60]},{38:[2,61],47:[2,61],52:[2,61],55:[2,61]},{38:[2,62],47:[2,62],52:[2,62],55:[2,62]},{27:146,28:[1,71]},{8:197,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,144],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],84:142,85:[1,56],86:[1,57],87:[1,55],88:[1,141],91:143,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],47:[2,48],52:[2,48],55:[2,48],70:[2,48],75:[2,48],83:[2,48],88:[2,48],90:[2,48],99:[2,48],101:[2,48],102:[2,48],103:[2,48],107:[2,48],115:[2,48],123:[2,48],125:[2,48],126:[2,48],129:[2,48],130:[2,48],131:[2,48],132:[2,48],133:[2,48],134:[2,48]},{1:[2,178],6:[2,178],25:[2,178],26:[2,178],47:[2,178],52:[2,178],55:[2,178],70:[2,178],75:[2,178],83:[2,178],88:[2,178],90:[2,178],99:[2,178],100:85,101:[2,178],102:[2,178],103:[2,178],106:86,107:[2,178],108:67,115:[2,178],123:[2,178],125:[2,178],126:[2,178],129:[1,76],130:[2,178],131:[2,178],132:[2,178],133:[2,178],134:[2,178]},{100:88,101:[1,63],103:[1,64],106:89,107:[1,66],108:67,123:[1,87]},{1:[2,179],6:[2,179],25:[2,179],26:[2,179],47:[2,179],52:[2,179],55:[2,179],70:[2,179],75:[2,179],83:[2,179],88:[2,179],90:[2,179],99:[2,179],100:85,101:[2,179],102:[2,179],103:[2,179],106:86,107:[2,179],108:67,115:[2,179],123:[2,179],125:[2,179],126:[2,179],129:[1,76],130:[2,179],131:[2,179],132:[2,179],133:[2,179],134:[2,179]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],47:[2,180],52:[2,180],55:[2,180],70:[2,180],75:[2,180],83:[2,180],88:[2,180],90:[2,180],99:[2,180],100:85,101:[2,180],102:[2,180],103:[2,180],106:86,107:[2,180],108:67,115:[2,180],123:[2,180],125:[2,180],126:[2,180],129:[1,76],130:[2,180],131:[2,180],132:[2,180],133:[2,180],134:[2,180]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],47:[2,181],52:[2,181],55:[2,181],64:[2,68],65:[2,68],66:[2,68],68:[2,68],70:[2,181],71:[2,68],75:[2,181],81:[2,68],82:[2,68],83:[2,181],88:[2,181],90:[2,181],99:[2,181],101:[2,181],102:[2,181],103:[2,181],107:[2,181],115:[2,181],123:[2,181],125:[2,181],126:[2,181],129:[2,181],130:[2,181],131:[2,181],132:[2,181],133:[2,181],134:[2,181]},{60:91,64:[1,93],65:[1,94],66:[1,95],67:96,68:[1,97],71:[1,98],78:90,81:[1,92],82:[2,103]},{60:100,64:[1,93],65:[1,94],66:[1,95],67:96,68:[1,97],71:[1,98],78:99,81:[1,92],82:[2,103]},{64:[2,71],65:[2,71],66:[2,71],68:[2,71],71:[2,71],81:[2,71],82:[2,71]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],47:[2,182],52:[2,182],55:[2,182],64:[2,68],65:[2,68],66:[2,68],68:[2,68],70:[2,182],71:[2,68],75:[2,182],81:[2,68],82:[2,68],83:[2,182],88:[2,182],90:[2,182],99:[2,182],101:[2,182],102:[2,182],103:[2,182],107:[2,182],115:[2,182],123:[2,182],125:[2,182],126:[2,182],129:[2,182],130:[2,182],131:[2,182],132:[2,182],133:[2,182],134:[2,182]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],47:[2,183],52:[2,183],55:[2,183],70:[2,183],75:[2,183],83:[2,183],88:[2,183],90:[2,183],99:[2,183],101:[2,183],102:[2,183],103:[2,183],107:[2,183],115:[2,183],123:[2,183],125:[2,183],126:[2,183],129:[2,183],130:[2,183],131:[2,183],132:[2,183],133:[2,183],134:[2,183]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],47:[2,184],52:[2,184],55:[2,184],70:[2,184],75:[2,184],83:[2,184],88:[2,184],90:[2,184],99:[2,184],101:[2,184],102:[2,184],103:[2,184],107:[2,184],115:[2,184],123:[2,184],125:[2,184],126:[2,184],129:[2,184],130:[2,184],131:[2,184],132:[2,184],133:[2,184],134:[2,184]},{8:202,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,203],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:204,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{5:205,25:[1,5],122:[1,206]},{1:[2,127],6:[2,127],25:[2,127],26:[2,127],47:[2,127],52:[2,127],55:[2,127],70:[2,127],75:[2,127],83:[2,127],88:[2,127],90:[2,127],94:207,95:[1,208],96:[1,209],99:[2,127],101:[2,127],102:[2,127],103:[2,127],107:[2,127],115:[2,127],123:[2,127],125:[2,127],126:[2,127],129:[2,127],130:[2,127],131:[2,127],132:[2,127],133:[2,127],134:[2,127]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],47:[2,139],52:[2,139],55:[2,139],70:[2,139],75:[2,139],83:[2,139],88:[2,139],90:[2,139],99:[2,139],101:[2,139],102:[2,139],103:[2,139],107:[2,139],115:[2,139],123:[2,139],125:[2,139],126:[2,139],129:[2,139],130:[2,139],131:[2,139],132:[2,139],133:[2,139],134:[2,139]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],47:[2,147],52:[2,147],55:[2,147],70:[2,147],75:[2,147],83:[2,147],88:[2,147],90:[2,147],99:[2,147],101:[2,147],102:[2,147],103:[2,147],107:[2,147],115:[2,147],123:[2,147],125:[2,147],126:[2,147],129:[2,147],130:[2,147],131:[2,147],132:[2,147],133:[2,147],134:[2,147]},{25:[1,210],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{117:211,119:212,120:[1,213]},{1:[2,92],6:[2,92],25:[2,92],26:[2,92],47:[2,92],52:[2,92],55:[2,92],70:[2,92],75:[2,92],83:[2,92],88:[2,92],90:[2,92],99:[2,92],101:[2,92],102:[2,92],103:[2,92],107:[2,92],115:[2,92],123:[2,92],125:[2,92],126:[2,92],129:[2,92],130:[2,92],131:[2,92],132:[2,92],133:[2,92],134:[2,92]},{8:214,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,95],5:215,6:[2,95],25:[1,5],26:[2,95],47:[2,95],52:[2,95],55:[2,95],64:[2,68],65:[2,68],66:[2,68],68:[2,68],70:[2,95],71:[2,68],75:[2,95],77:[1,216],81:[2,68],82:[2,68],83:[2,95],88:[2,95],90:[2,95],99:[2,95],101:[2,95],102:[2,95],103:[2,95],107:[2,95],115:[2,95],123:[2,95],125:[2,95],126:[2,95],129:[2,95],130:[2,95],131:[2,95],132:[2,95],133:[2,95],134:[2,95]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],47:[2,132],52:[2,132],55:[2,132],70:[2,132],75:[2,132],83:[2,132],88:[2,132],90:[2,132],99:[2,132],100:85,101:[2,132],102:[2,132],103:[2,132],106:86,107:[2,132],108:67,115:[2,132],123:[2,132],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,44],6:[2,44],26:[2,44],99:[2,44],100:85,101:[2,44],103:[2,44],106:86,107:[2,44],108:67,123:[2,44],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{6:[1,72],99:[1,217]},{4:218,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,123],25:[2,123],52:[2,123],55:[1,220],88:[2,123],89:219,90:[1,188],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],38:[2,110],47:[2,110],52:[2,110],55:[2,110],64:[2,110],65:[2,110],66:[2,110],68:[2,110],70:[2,110],71:[2,110],75:[2,110],81:[2,110],82:[2,110],83:[2,110],88:[2,110],90:[2,110],99:[2,110],101:[2,110],102:[2,110],103:[2,110],107:[2,110],113:[2,110],114:[2,110],115:[2,110],123:[2,110],125:[2,110],126:[2,110],129:[2,110],130:[2,110],131:[2,110],132:[2,110],133:[2,110],134:[2,110]},{6:[2,51],25:[2,51],51:221,52:[1,222],88:[2,51]},{6:[2,118],25:[2,118],26:[2,118],52:[2,118],83:[2,118],88:[2,118]},{8:197,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,144],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],84:223,85:[1,56],86:[1,57],87:[1,55],91:143,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,124],25:[2,124],26:[2,124],52:[2,124],83:[2,124],88:[2,124]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],38:[2,109],41:[2,109],47:[2,109],52:[2,109],55:[2,109],64:[2,109],65:[2,109],66:[2,109],68:[2,109],70:[2,109],71:[2,109],75:[2,109],77:[2,109],81:[2,109],82:[2,109],83:[2,109],88:[2,109],90:[2,109],99:[2,109],101:[2,109],102:[2,109],103:[2,109],107:[2,109],115:[2,109],123:[2,109],125:[2,109],126:[2,109],127:[2,109],128:[2,109],129:[2,109],130:[2,109],131:[2,109],132:[2,109],133:[2,109],134:[2,109],135:[2,109]},{5:224,25:[1,5],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],47:[2,135],52:[2,135],55:[2,135],70:[2,135],75:[2,135],83:[2,135],88:[2,135],90:[2,135],99:[2,135],100:85,101:[1,63],102:[1,225],103:[1,64],106:86,107:[1,66],108:67,115:[2,135],123:[2,135],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],47:[2,137],52:[2,137],55:[2,137],70:[2,137],75:[2,137],83:[2,137],88:[2,137],90:[2,137],99:[2,137],100:85,101:[1,63],102:[1,226],103:[1,64],106:86,107:[1,66],108:67,115:[2,137],123:[2,137],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],47:[2,143],52:[2,143],55:[2,143],70:[2,143],75:[2,143],83:[2,143],88:[2,143],90:[2,143],99:[2,143],101:[2,143],102:[2,143],103:[2,143],107:[2,143],115:[2,143],123:[2,143],125:[2,143],126:[2,143],129:[2,143],130:[2,143],131:[2,143],132:[2,143],133:[2,143],134:[2,143]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],47:[2,144],52:[2,144],55:[2,144],70:[2,144],75:[2,144],83:[2,144],88:[2,144],90:[2,144],99:[2,144],100:85,101:[1,63],102:[2,144],103:[1,64],106:86,107:[1,66],108:67,115:[2,144],123:[2,144],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],47:[2,148],52:[2,148],55:[2,148],70:[2,148],75:[2,148],83:[2,148],88:[2,148],90:[2,148],99:[2,148],101:[2,148],102:[2,148],103:[2,148],107:[2,148],115:[2,148],123:[2,148],125:[2,148],126:[2,148],129:[2,148],130:[2,148],131:[2,148],132:[2,148],133:[2,148],134:[2,148]},{113:[2,150],114:[2,150]},{27:156,28:[1,71],56:157,57:158,73:[1,68],87:[1,112],110:227,112:155},{52:[1,228],113:[2,155],114:[2,155]},{52:[2,152],113:[2,152],114:[2,152]},{52:[2,153],113:[2,153],114:[2,153]},{52:[2,154],113:[2,154],114:[2,154]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],47:[2,149],52:[2,149],55:[2,149],70:[2,149],75:[2,149],83:[2,149],88:[2,149],90:[2,149],99:[2,149],101:[2,149],102:[2,149],103:[2,149],107:[2,149],115:[2,149],123:[2,149],125:[2,149],126:[2,149],129:[2,149],130:[2,149],131:[2,149],132:[2,149],133:[2,149],134:[2,149]},{8:229,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:230,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,51],25:[2,51],51:231,52:[1,232],75:[2,51]},{6:[2,87],25:[2,87],26:[2,87],52:[2,87],75:[2,87]},{6:[2,37],25:[2,37],26:[2,37],41:[1,233],52:[2,37],75:[2,37]},{6:[2,40],25:[2,40],26:[2,40],52:[2,40],75:[2,40]},{6:[2,41],25:[2,41],26:[2,41],41:[2,41],52:[2,41],75:[2,41]},{6:[2,42],25:[2,42],26:[2,42],41:[2,42],52:[2,42],75:[2,42]},{6:[2,43],25:[2,43],26:[2,43],41:[2,43],52:[2,43],75:[2,43]},{1:[2,5],6:[2,5],26:[2,5],99:[2,5]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],47:[2,25],52:[2,25],55:[2,25],70:[2,25],75:[2,25],83:[2,25],88:[2,25],90:[2,25],95:[2,25],96:[2,25],99:[2,25],101:[2,25],102:[2,25],103:[2,25],107:[2,25],115:[2,25],118:[2,25],120:[2,25],123:[2,25],125:[2,25],126:[2,25],129:[2,25],130:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],47:[2,186],52:[2,186],55:[2,186],70:[2,186],75:[2,186],83:[2,186],88:[2,186],90:[2,186],99:[2,186],100:85,101:[2,186],102:[2,186],103:[2,186],106:86,107:[2,186],108:67,115:[2,186],123:[2,186],125:[2,186],126:[2,186],129:[1,76],130:[1,79],131:[2,186],132:[2,186],133:[2,186],134:[2,186]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],47:[2,187],52:[2,187],55:[2,187],70:[2,187],75:[2,187],83:[2,187],88:[2,187],90:[2,187],99:[2,187],100:85,101:[2,187],102:[2,187],103:[2,187],106:86,107:[2,187],108:67,115:[2,187],123:[2,187],125:[2,187],126:[2,187],129:[1,76],130:[1,79],131:[2,187],132:[2,187],133:[2,187],134:[2,187]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],47:[2,188],52:[2,188],55:[2,188],70:[2,188],75:[2,188],83:[2,188],88:[2,188],90:[2,188],99:[2,188],100:85,101:[2,188],102:[2,188],103:[2,188],106:86,107:[2,188],108:67,115:[2,188],123:[2,188],125:[2,188],126:[2,188],129:[1,76],130:[2,188],131:[2,188],132:[2,188],133:[2,188],134:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],47:[2,189],52:[2,189],55:[2,189],70:[2,189],75:[2,189],83:[2,189],88:[2,189],90:[2,189],99:[2,189],100:85,101:[2,189],102:[2,189],103:[2,189],106:86,107:[2,189],108:67,115:[2,189],123:[2,189],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[2,189],132:[2,189],133:[2,189],134:[2,189]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],47:[2,190],52:[2,190],55:[2,190],70:[2,190],75:[2,190],83:[2,190],88:[2,190],90:[2,190],99:[2,190],100:85,101:[2,190],102:[2,190],103:[2,190],106:86,107:[2,190],108:67,115:[2,190],123:[2,190],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[2,190],133:[2,190],134:[1,83]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],47:[2,191],52:[2,191],55:[2,191],70:[2,191],75:[2,191],83:[2,191],88:[2,191],90:[2,191],99:[2,191],100:85,101:[2,191],102:[2,191],103:[2,191],106:86,107:[2,191],108:67,115:[2,191],123:[2,191],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[2,191],134:[1,83]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],47:[2,192],52:[2,192],55:[2,192],70:[2,192],75:[2,192],83:[2,192],88:[2,192],90:[2,192],99:[2,192],100:85,101:[2,192],102:[2,192],103:[2,192],106:86,107:[2,192],108:67,115:[2,192],123:[2,192],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[2,192],133:[2,192],134:[2,192]},{1:[2,177],6:[2,177],25:[2,177],26:[2,177],47:[2,177],52:[2,177],55:[2,177],70:[2,177],75:[2,177],83:[2,177],88:[2,177],90:[2,177],99:[2,177],100:85,101:[1,63],102:[2,177],103:[1,64],106:86,107:[1,66],108:67,115:[2,177],123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,176],6:[2,176],25:[2,176],26:[2,176],47:[2,176],52:[2,176],55:[2,176],70:[2,176],75:[2,176],83:[2,176],88:[2,176],90:[2,176],99:[2,176],100:85,101:[1,63],102:[2,176],103:[1,64],106:86,107:[1,66],108:67,115:[2,176],123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,99],6:[2,99],25:[2,99],26:[2,99],47:[2,99],52:[2,99],55:[2,99],64:[2,99],65:[2,99],66:[2,99],68:[2,99],70:[2,99],71:[2,99],75:[2,99],81:[2,99],82:[2,99],83:[2,99],88:[2,99],90:[2,99],99:[2,99],101:[2,99],102:[2,99],103:[2,99],107:[2,99],115:[2,99],123:[2,99],125:[2,99],126:[2,99],129:[2,99],130:[2,99],131:[2,99],132:[2,99],133:[2,99],134:[2,99]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],38:[2,76],47:[2,76],52:[2,76],55:[2,76],64:[2,76],65:[2,76],66:[2,76],68:[2,76],70:[2,76],71:[2,76],75:[2,76],77:[2,76],81:[2,76],82:[2,76],83:[2,76],88:[2,76],90:[2,76],99:[2,76],101:[2,76],102:[2,76],103:[2,76],107:[2,76],115:[2,76],123:[2,76],125:[2,76],126:[2,76],127:[2,76],128:[2,76],129:[2,76],130:[2,76],131:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],38:[2,77],47:[2,77],52:[2,77],55:[2,77],64:[2,77],65:[2,77],66:[2,77],68:[2,77],70:[2,77],71:[2,77],75:[2,77],77:[2,77],81:[2,77],82:[2,77],83:[2,77],88:[2,77],90:[2,77],99:[2,77],101:[2,77],102:[2,77],103:[2,77],107:[2,77],115:[2,77],123:[2,77],125:[2,77],126:[2,77],127:[2,77],128:[2,77],129:[2,77],130:[2,77],131:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],38:[2,78],47:[2,78],52:[2,78],55:[2,78],64:[2,78],65:[2,78],66:[2,78],68:[2,78],70:[2,78],71:[2,78],75:[2,78],77:[2,78],81:[2,78],82:[2,78],83:[2,78],88:[2,78],90:[2,78],99:[2,78],101:[2,78],102:[2,78],103:[2,78],107:[2,78],115:[2,78],123:[2,78],125:[2,78],126:[2,78],127:[2,78],128:[2,78],129:[2,78],130:[2,78],131:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78]},{70:[1,234]},{55:[1,189],70:[2,83],89:235,90:[1,188],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{70:[2,84]},{8:236,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{12:[2,112],28:[2,112],30:[2,112],31:[2,112],33:[2,112],34:[2,112],35:[2,112],36:[2,112],43:[2,112],44:[2,112],45:[2,112],49:[2,112],50:[2,112],70:[2,112],73:[2,112],76:[2,112],80:[2,112],85:[2,112],86:[2,112],87:[2,112],93:[2,112],97:[2,112],98:[2,112],101:[2,112],103:[2,112],105:[2,112],107:[2,112],116:[2,112],122:[2,112],124:[2,112],125:[2,112],126:[2,112],127:[2,112],128:[2,112]},{12:[2,113],28:[2,113],30:[2,113],31:[2,113],33:[2,113],34:[2,113],35:[2,113],36:[2,113],43:[2,113],44:[2,113],45:[2,113],49:[2,113],50:[2,113],70:[2,113],73:[2,113],76:[2,113],80:[2,113],85:[2,113],86:[2,113],87:[2,113],93:[2,113],97:[2,113],98:[2,113],101:[2,113],103:[2,113],105:[2,113],107:[2,113],116:[2,113],122:[2,113],124:[2,113],125:[2,113],126:[2,113],127:[2,113],128:[2,113]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],38:[2,82],47:[2,82],52:[2,82],55:[2,82],64:[2,82],65:[2,82],66:[2,82],68:[2,82],70:[2,82],71:[2,82],75:[2,82],77:[2,82],81:[2,82],82:[2,82],83:[2,82],88:[2,82],90:[2,82],99:[2,82],101:[2,82],102:[2,82],103:[2,82],107:[2,82],115:[2,82],123:[2,82],125:[2,82],126:[2,82],127:[2,82],128:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],47:[2,100],52:[2,100],55:[2,100],64:[2,100],65:[2,100],66:[2,100],68:[2,100],70:[2,100],71:[2,100],75:[2,100],81:[2,100],82:[2,100],83:[2,100],88:[2,100],90:[2,100],99:[2,100],101:[2,100],102:[2,100],103:[2,100],107:[2,100],115:[2,100],123:[2,100],125:[2,100],126:[2,100],129:[2,100],130:[2,100],131:[2,100],132:[2,100],133:[2,100],134:[2,100]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],47:[2,34],52:[2,34],55:[2,34],70:[2,34],75:[2,34],83:[2,34],88:[2,34],90:[2,34],99:[2,34],100:85,101:[2,34],102:[2,34],103:[2,34],106:86,107:[2,34],108:67,115:[2,34],123:[2,34],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{8:237,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:238,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],47:[2,105],52:[2,105],55:[2,105],64:[2,105],65:[2,105],66:[2,105],68:[2,105],70:[2,105],71:[2,105],75:[2,105],81:[2,105],82:[2,105],83:[2,105],88:[2,105],90:[2,105],99:[2,105],101:[2,105],102:[2,105],103:[2,105],107:[2,105],115:[2,105],123:[2,105],125:[2,105],126:[2,105],129:[2,105],130:[2,105],131:[2,105],132:[2,105],133:[2,105],134:[2,105]},{6:[2,51],25:[2,51],51:239,52:[1,222],83:[2,51]},{6:[2,123],25:[2,123],26:[2,123],52:[2,123],55:[1,240],83:[2,123],88:[2,123],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{48:241,49:[1,58],50:[1,59]},{27:107,28:[1,71],42:108,53:242,54:106,56:109,57:110,73:[1,68],86:[1,111],87:[1,112]},{47:[2,57],52:[2,57]},{8:243,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],47:[2,193],52:[2,193],55:[2,193],70:[2,193],75:[2,193],83:[2,193],88:[2,193],90:[2,193],99:[2,193],100:85,101:[2,193],102:[2,193],103:[2,193],106:86,107:[2,193],108:67,115:[2,193],123:[2,193],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{8:244,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],47:[2,195],52:[2,195],55:[2,195],70:[2,195],75:[2,195],83:[2,195],88:[2,195],90:[2,195],99:[2,195],100:85,101:[2,195],102:[2,195],103:[2,195],106:86,107:[2,195],108:67,115:[2,195],123:[2,195],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,175],6:[2,175],25:[2,175],26:[2,175],47:[2,175],52:[2,175],55:[2,175],70:[2,175],75:[2,175],83:[2,175],88:[2,175],90:[2,175],99:[2,175],101:[2,175],102:[2,175],103:[2,175],107:[2,175],115:[2,175],123:[2,175],125:[2,175],126:[2,175],129:[2,175],130:[2,175],131:[2,175],132:[2,175],133:[2,175],134:[2,175]},{8:245,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,128],6:[2,128],25:[2,128],26:[2,128],47:[2,128],52:[2,128],55:[2,128],70:[2,128],75:[2,128],83:[2,128],88:[2,128],90:[2,128],95:[1,246],99:[2,128],101:[2,128],102:[2,128],103:[2,128],107:[2,128],115:[2,128],123:[2,128],125:[2,128],126:[2,128],129:[2,128],130:[2,128],131:[2,128],132:[2,128],133:[2,128],134:[2,128]},{5:247,25:[1,5]},{27:248,28:[1,71]},{117:249,119:212,120:[1,213]},{26:[1,250],118:[1,251],119:252,120:[1,213]},{26:[2,168],118:[2,168],120:[2,168]},{8:254,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],92:253,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,93],5:255,6:[2,93],25:[1,5],26:[2,93],47:[2,93],52:[2,93],55:[2,93],70:[2,93],75:[2,93],83:[2,93],88:[2,93],90:[2,93],99:[2,93],100:85,101:[1,63],102:[2,93],103:[1,64],106:86,107:[1,66],108:67,115:[2,93],123:[2,93],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,96],6:[2,96],25:[2,96],26:[2,96],47:[2,96],52:[2,96],55:[2,96],70:[2,96],75:[2,96],83:[2,96],88:[2,96],90:[2,96],99:[2,96],101:[2,96],102:[2,96],103:[2,96],107:[2,96],115:[2,96],123:[2,96],125:[2,96],126:[2,96],129:[2,96],130:[2,96],131:[2,96],132:[2,96],133:[2,96],134:[2,96]},{8:256,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],47:[2,133],52:[2,133],55:[2,133],64:[2,133],65:[2,133],66:[2,133],68:[2,133],70:[2,133],71:[2,133],75:[2,133],81:[2,133],82:[2,133],83:[2,133],88:[2,133],90:[2,133],99:[2,133],101:[2,133],102:[2,133],103:[2,133],107:[2,133],115:[2,133],123:[2,133],125:[2,133],126:[2,133],129:[2,133],130:[2,133],131:[2,133],132:[2,133],133:[2,133],134:[2,133]},{6:[1,72],26:[1,257]},{8:258,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,63],12:[2,113],25:[2,63],28:[2,113],30:[2,113],31:[2,113],33:[2,113],34:[2,113],35:[2,113],36:[2,113],43:[2,113],44:[2,113],45:[2,113],49:[2,113],50:[2,113],52:[2,63],73:[2,113],76:[2,113],80:[2,113],85:[2,113],86:[2,113],87:[2,113],88:[2,63],93:[2,113],97:[2,113],98:[2,113],101:[2,113],103:[2,113],105:[2,113],107:[2,113],116:[2,113],122:[2,113],124:[2,113],125:[2,113],126:[2,113],127:[2,113],128:[2,113]},{6:[1,260],25:[1,261],88:[1,259]},{6:[2,52],8:197,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[2,52],26:[2,52],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],83:[2,52],85:[1,56],86:[1,57],87:[1,55],88:[2,52],91:262,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,51],25:[2,51],26:[2,51],51:263,52:[1,222]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],47:[2,172],52:[2,172],55:[2,172],70:[2,172],75:[2,172],83:[2,172],88:[2,172],90:[2,172],99:[2,172],101:[2,172],102:[2,172],103:[2,172],107:[2,172],115:[2,172],118:[2,172],123:[2,172],125:[2,172],126:[2,172],129:[2,172],130:[2,172],131:[2,172],132:[2,172],133:[2,172],134:[2,172]},{8:264,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:265,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{113:[2,151],114:[2,151]},{27:156,28:[1,71],56:157,57:158,73:[1,68],87:[1,112],112:266},{1:[2,157],6:[2,157],25:[2,157],26:[2,157],47:[2,157],52:[2,157],55:[2,157],70:[2,157],75:[2,157],83:[2,157],88:[2,157],90:[2,157],99:[2,157],100:85,101:[2,157],102:[1,267],103:[2,157],106:86,107:[2,157],108:67,115:[1,268],123:[2,157],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,158],6:[2,158],25:[2,158],26:[2,158],47:[2,158],52:[2,158],55:[2,158],70:[2,158],75:[2,158],83:[2,158],88:[2,158],90:[2,158],99:[2,158],100:85,101:[2,158],102:[1,269],103:[2,158],106:86,107:[2,158],108:67,115:[2,158],123:[2,158],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{6:[1,271],25:[1,272],75:[1,270]},{6:[2,52],11:165,25:[2,52],26:[2,52],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],39:273,40:164,42:168,44:[1,46],75:[2,52],86:[1,111]},{8:274,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,275],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],38:[2,81],47:[2,81],52:[2,81],55:[2,81],64:[2,81],65:[2,81],66:[2,81],68:[2,81],70:[2,81],71:[2,81],75:[2,81],77:[2,81],81:[2,81],82:[2,81],83:[2,81],88:[2,81],90:[2,81],99:[2,81],101:[2,81],102:[2,81],103:[2,81],107:[2,81],115:[2,81],123:[2,81],125:[2,81],126:[2,81],127:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81]},{8:276,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,70:[2,116],73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{70:[2,117],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],47:[2,35],52:[2,35],55:[2,35],70:[2,35],75:[2,35],83:[2,35],88:[2,35],90:[2,35],99:[2,35],100:85,101:[2,35],102:[2,35],103:[2,35],106:86,107:[2,35],108:67,115:[2,35],123:[2,35],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{26:[1,277],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{6:[1,260],25:[1,261],83:[1,278]},{6:[2,63],25:[2,63],26:[2,63],52:[2,63],83:[2,63],88:[2,63]},{5:279,25:[1,5]},{47:[2,55],52:[2,55]},{47:[2,58],52:[2,58],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{26:[1,280],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{5:281,25:[1,5],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{5:282,25:[1,5]},{1:[2,129],6:[2,129],25:[2,129],26:[2,129],47:[2,129],52:[2,129],55:[2,129],70:[2,129],75:[2,129],83:[2,129],88:[2,129],90:[2,129],99:[2,129],101:[2,129],102:[2,129],103:[2,129],107:[2,129],115:[2,129],123:[2,129],125:[2,129],126:[2,129],129:[2,129],130:[2,129],131:[2,129],132:[2,129],133:[2,129],134:[2,129]},{5:283,25:[1,5]},{26:[1,284],118:[1,285],119:252,120:[1,213]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],47:[2,166],52:[2,166],55:[2,166],70:[2,166],75:[2,166],83:[2,166],88:[2,166],90:[2,166],99:[2,166],101:[2,166],102:[2,166],103:[2,166],107:[2,166],115:[2,166],123:[2,166],125:[2,166],126:[2,166],129:[2,166],130:[2,166],131:[2,166],132:[2,166],133:[2,166],134:[2,166]},{5:286,25:[1,5]},{26:[2,169],118:[2,169],120:[2,169]},{5:287,25:[1,5],52:[1,288]},{25:[2,125],52:[2,125],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,94],6:[2,94],25:[2,94],26:[2,94],47:[2,94],52:[2,94],55:[2,94],70:[2,94],75:[2,94],83:[2,94],88:[2,94],90:[2,94],99:[2,94],101:[2,94],102:[2,94],103:[2,94],107:[2,94],115:[2,94],123:[2,94],125:[2,94],126:[2,94],129:[2,94],130:[2,94],131:[2,94],132:[2,94],133:[2,94],134:[2,94]},{1:[2,97],5:289,6:[2,97],25:[1,5],26:[2,97],47:[2,97],52:[2,97],55:[2,97],70:[2,97],75:[2,97],83:[2,97],88:[2,97],90:[2,97],99:[2,97],100:85,101:[1,63],102:[2,97],103:[1,64],106:86,107:[1,66],108:67,115:[2,97],123:[2,97],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{99:[1,290]},{88:[1,291],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],38:[2,111],47:[2,111],52:[2,111],55:[2,111],64:[2,111],65:[2,111],66:[2,111],68:[2,111],70:[2,111],71:[2,111],75:[2,111],81:[2,111],82:[2,111],83:[2,111],88:[2,111],90:[2,111],99:[2,111],101:[2,111],102:[2,111],103:[2,111],107:[2,111],113:[2,111],114:[2,111],115:[2,111],123:[2,111],125:[2,111],126:[2,111],129:[2,111],130:[2,111],131:[2,111],132:[2,111],133:[2,111],134:[2,111]},{8:197,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],91:292,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:197,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,144],27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,58:145,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],84:293,85:[1,56],86:[1,57],87:[1,55],91:143,93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[2,119],25:[2,119],26:[2,119],52:[2,119],83:[2,119],88:[2,119]},{6:[1,260],25:[1,261],26:[1,294]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],47:[2,136],52:[2,136],55:[2,136],70:[2,136],75:[2,136],83:[2,136],88:[2,136],90:[2,136],99:[2,136],100:85,101:[1,63],102:[2,136],103:[1,64],106:86,107:[1,66],108:67,115:[2,136],123:[2,136],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],47:[2,138],52:[2,138],55:[2,138],70:[2,138],75:[2,138],83:[2,138],88:[2,138],90:[2,138],99:[2,138],100:85,101:[1,63],102:[2,138],103:[1,64],106:86,107:[1,66],108:67,115:[2,138],123:[2,138],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{113:[2,156],114:[2,156]},{8:295,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:296,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:297,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],38:[2,85],47:[2,85],52:[2,85],55:[2,85],64:[2,85],65:[2,85],66:[2,85],68:[2,85],70:[2,85],71:[2,85],75:[2,85],81:[2,85],82:[2,85],83:[2,85],88:[2,85],90:[2,85],99:[2,85],101:[2,85],102:[2,85],103:[2,85],107:[2,85],113:[2,85],114:[2,85],115:[2,85],123:[2,85],125:[2,85],126:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85]},{11:165,27:166,28:[1,71],29:167,30:[1,69],31:[1,70],39:298,40:164,42:168,44:[1,46],86:[1,111]},{6:[2,86],11:165,25:[2,86],26:[2,86],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],39:163,40:164,42:168,44:[1,46],52:[2,86],74:299,86:[1,111]},{6:[2,88],25:[2,88],26:[2,88],52:[2,88],75:[2,88]},{6:[2,38],25:[2,38],26:[2,38],52:[2,38],75:[2,38],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{8:300,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{70:[2,115],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],47:[2,36],52:[2,36],55:[2,36],70:[2,36],75:[2,36],83:[2,36],88:[2,36],90:[2,36],99:[2,36],101:[2,36],102:[2,36],103:[2,36],107:[2,36],115:[2,36],123:[2,36],125:[2,36],126:[2,36],129:[2,36],130:[2,36],131:[2,36],132:[2,36],133:[2,36],134:[2,36]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],47:[2,106],52:[2,106],55:[2,106],64:[2,106],65:[2,106],66:[2,106],68:[2,106],70:[2,106],71:[2,106],75:[2,106],81:[2,106],82:[2,106],83:[2,106],88:[2,106],90:[2,106],99:[2,106],101:[2,106],102:[2,106],103:[2,106],107:[2,106],115:[2,106],123:[2,106],125:[2,106],126:[2,106],129:[2,106],130:[2,106],131:[2,106],132:[2,106],133:[2,106],134:[2,106]},{1:[2,47],6:[2,47],25:[2,47],26:[2,47],47:[2,47],52:[2,47],55:[2,47],70:[2,47],75:[2,47],83:[2,47],88:[2,47],90:[2,47],99:[2,47],101:[2,47],102:[2,47],103:[2,47],107:[2,47],115:[2,47],123:[2,47],125:[2,47],126:[2,47],129:[2,47],130:[2,47],131:[2,47],132:[2,47],133:[2,47],134:[2,47]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],47:[2,194],52:[2,194],55:[2,194],70:[2,194],75:[2,194],83:[2,194],88:[2,194],90:[2,194],99:[2,194],101:[2,194],102:[2,194],103:[2,194],107:[2,194],115:[2,194],123:[2,194],125:[2,194],126:[2,194],129:[2,194],130:[2,194],131:[2,194],132:[2,194],133:[2,194],134:[2,194]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],47:[2,173],52:[2,173],55:[2,173],70:[2,173],75:[2,173],83:[2,173],88:[2,173],90:[2,173],99:[2,173],101:[2,173],102:[2,173],103:[2,173],107:[2,173],115:[2,173],118:[2,173],123:[2,173],125:[2,173],126:[2,173],129:[2,173],130:[2,173],131:[2,173],132:[2,173],133:[2,173],134:[2,173]},{1:[2,130],6:[2,130],25:[2,130],26:[2,130],47:[2,130],52:[2,130],55:[2,130],70:[2,130],75:[2,130],83:[2,130],88:[2,130],90:[2,130],99:[2,130],101:[2,130],102:[2,130],103:[2,130],107:[2,130],115:[2,130],123:[2,130],125:[2,130],126:[2,130],129:[2,130],130:[2,130],131:[2,130],132:[2,130],133:[2,130],134:[2,130]},{1:[2,131],6:[2,131],25:[2,131],26:[2,131],47:[2,131],52:[2,131],55:[2,131],70:[2,131],75:[2,131],83:[2,131],88:[2,131],90:[2,131],95:[2,131],99:[2,131],101:[2,131],102:[2,131],103:[2,131],107:[2,131],115:[2,131],123:[2,131],125:[2,131],126:[2,131],129:[2,131],130:[2,131],131:[2,131],132:[2,131],133:[2,131],134:[2,131]},{1:[2,164],6:[2,164],25:[2,164],26:[2,164],47:[2,164],52:[2,164],55:[2,164],70:[2,164],75:[2,164],83:[2,164],88:[2,164],90:[2,164],99:[2,164],101:[2,164],102:[2,164],103:[2,164],107:[2,164],115:[2,164],123:[2,164],125:[2,164],126:[2,164],129:[2,164],130:[2,164],131:[2,164],132:[2,164],133:[2,164],134:[2,164]},{5:301,25:[1,5]},{26:[1,302]},{6:[1,303],26:[2,170],118:[2,170],120:[2,170]},{8:304,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],47:[2,98],52:[2,98],55:[2,98],70:[2,98],75:[2,98],83:[2,98],88:[2,98],90:[2,98],99:[2,98],101:[2,98],102:[2,98],103:[2,98],107:[2,98],115:[2,98],123:[2,98],125:[2,98],126:[2,98],129:[2,98],130:[2,98],131:[2,98],132:[2,98],133:[2,98],134:[2,98]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],47:[2,134],52:[2,134],55:[2,134],64:[2,134],65:[2,134],66:[2,134],68:[2,134],70:[2,134],71:[2,134],75:[2,134],81:[2,134],82:[2,134],83:[2,134],88:[2,134],90:[2,134],99:[2,134],101:[2,134],102:[2,134],103:[2,134],107:[2,134],115:[2,134],123:[2,134],125:[2,134],126:[2,134],129:[2,134],130:[2,134],131:[2,134],132:[2,134],133:[2,134],134:[2,134]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],47:[2,114],52:[2,114],55:[2,114],64:[2,114],65:[2,114],66:[2,114],68:[2,114],70:[2,114],71:[2,114],75:[2,114],81:[2,114],82:[2,114],83:[2,114],88:[2,114],90:[2,114],99:[2,114],101:[2,114],102:[2,114],103:[2,114],107:[2,114],115:[2,114],123:[2,114],125:[2,114],126:[2,114],129:[2,114],130:[2,114],131:[2,114],132:[2,114],133:[2,114],134:[2,114]},{6:[2,120],25:[2,120],26:[2,120],52:[2,120],83:[2,120],88:[2,120]},{6:[2,51],25:[2,51],26:[2,51],51:305,52:[1,222]},{6:[2,121],25:[2,121],26:[2,121],52:[2,121],83:[2,121],88:[2,121]},{1:[2,159],6:[2,159],25:[2,159],26:[2,159],47:[2,159],52:[2,159],55:[2,159],70:[2,159],75:[2,159],83:[2,159],88:[2,159],90:[2,159],99:[2,159],100:85,101:[2,159],102:[2,159],103:[2,159],106:86,107:[2,159],108:67,115:[1,306],123:[2,159],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,161],6:[2,161],25:[2,161],26:[2,161],47:[2,161],52:[2,161],55:[2,161],70:[2,161],75:[2,161],83:[2,161],88:[2,161],90:[2,161],99:[2,161],100:85,101:[2,161],102:[1,307],103:[2,161],106:86,107:[2,161],108:67,115:[2,161],123:[2,161],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,160],6:[2,160],25:[2,160],26:[2,160],47:[2,160],52:[2,160],55:[2,160],70:[2,160],75:[2,160],83:[2,160],88:[2,160],90:[2,160],99:[2,160],100:85,101:[2,160],102:[2,160],103:[2,160],106:86,107:[2,160],108:67,115:[2,160],123:[2,160],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{6:[2,89],25:[2,89],26:[2,89],52:[2,89],75:[2,89]},{6:[2,51],25:[2,51],26:[2,51],51:308,52:[1,232]},{26:[1,309],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{26:[1,310]},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],47:[2,167],52:[2,167],55:[2,167],70:[2,167],75:[2,167],83:[2,167],88:[2,167],90:[2,167],99:[2,167],101:[2,167],102:[2,167],103:[2,167],107:[2,167],115:[2,167],123:[2,167],125:[2,167],126:[2,167],129:[2,167],130:[2,167],131:[2,167],132:[2,167],133:[2,167],134:[2,167]},{26:[2,171],118:[2,171],120:[2,171]},{25:[2,126],52:[2,126],100:85,101:[1,63],103:[1,64],106:86,107:[1,66],108:67,123:[1,84],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{6:[1,260],25:[1,261],26:[1,311]},{8:312,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{8:313,9:115,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:60,28:[1,71],29:49,30:[1,69],31:[1,70],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:23,42:61,43:[1,45],44:[1,46],45:[1,29],48:30,49:[1,58],50:[1,59],56:47,57:48,59:36,61:25,62:26,63:27,73:[1,68],76:[1,43],80:[1,28],85:[1,56],86:[1,57],87:[1,55],93:[1,38],97:[1,44],98:[1,54],100:39,101:[1,63],103:[1,64],104:40,105:[1,65],106:41,107:[1,66],108:67,116:[1,42],121:37,122:[1,62],124:[1,31],125:[1,32],126:[1,33],127:[1,34],128:[1,35]},{6:[1,271],25:[1,272],26:[1,314]},{6:[2,39],25:[2,39],26:[2,39],52:[2,39],75:[2,39]},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],47:[2,165],52:[2,165],55:[2,165],70:[2,165],75:[2,165],83:[2,165],88:[2,165],90:[2,165],99:[2,165],101:[2,165],102:[2,165],103:[2,165],107:[2,165],115:[2,165],123:[2,165],125:[2,165],126:[2,165],129:[2,165],130:[2,165],131:[2,165],132:[2,165],133:[2,165],134:[2,165]},{6:[2,122],25:[2,122],26:[2,122],52:[2,122],83:[2,122],88:[2,122]},{1:[2,162],6:[2,162],25:[2,162],26:[2,162],47:[2,162],52:[2,162],55:[2,162],70:[2,162],75:[2,162],83:[2,162],88:[2,162],90:[2,162],99:[2,162],100:85,101:[2,162],102:[2,162],103:[2,162],106:86,107:[2,162],108:67,115:[2,162],123:[2,162],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{1:[2,163],6:[2,163],25:[2,163],26:[2,163],47:[2,163],52:[2,163],55:[2,163],70:[2,163],75:[2,163],83:[2,163],88:[2,163],90:[2,163],99:[2,163],100:85,101:[2,163],102:[2,163],103:[2,163],106:86,107:[2,163],108:67,115:[2,163],123:[2,163],125:[1,78],126:[1,77],129:[1,76],130:[1,79],131:[1,80],132:[1,81],133:[1,82],134:[1,83]},{6:[2,90],25:[2,90],26:[2,90],52:[2,90],75:[2,90]}], -defaultActions: {58:[2,49],59:[2,50],73:[2,3],92:[2,104],186:[2,84]}, -parseError: function parseError(str, hash) { - throw new Error(str); -}, -parse: function parse(input) { - var self = this, - stack = [0], - vstack = [null], // semantic value stack - lstack = [], // location stack - table = this.table, - yytext = '', - yylineno = 0, - yyleng = 0, - recovering = 0, - TERROR = 2, - EOF = 1; - - //this.reductionCount = this.shiftCount = 0; - - this.lexer.setInput(input); - this.lexer.yy = this.yy; - this.yy.lexer = this.lexer; - if (typeof this.lexer.yylloc == 'undefined') - this.lexer.yylloc = {}; - var yyloc = this.lexer.yylloc; - lstack.push(yyloc); - - if (typeof this.yy.parseError === 'function') - this.parseError = this.yy.parseError; - - function popStack (n) { - stack.length = stack.length - 2*n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - - function lex() { - var token; - token = self.lexer.lex() || 1; // $end = 1 - // if token isn't its numeric value, convert - if (typeof token !== 'number') { - token = self.symbols_[token] || token; - } - return token; - }; - - var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected; - while (true) { - // retreive state number from top of stack - state = stack[stack.length-1]; - - // use default actions if available - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol == null) - symbol = lex(); - // read action for current state and first input - action = table[state] && table[state][symbol]; - } - - // handle parse error - if (typeof action === 'undefined' || !action.length || !action[0]) { - - if (!recovering) { - // Report error - expected = []; - for (p in table[state]) if (this.terminals_[p] && p > 2) { - expected.push("'"+this.terminals_[p]+"'"); - } - var errStr = ''; - if (this.lexer.showPosition) { - errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', '); - } else { - errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " + - (symbol == 1 /*EOF*/ ? "end of input" : - ("'"+(this.terminals_[symbol] || symbol)+"'")); - } - this.parseError(errStr, - {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); - } - - // just recovered from another error - if (recovering == 3) { - if (symbol == EOF) { - throw new Error(errStr || 'Parsing halted.'); - } - - // discard current lookahead and grab another - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - symbol = lex(); - } - - // try to recover from error - while (1) { - // check for error recovery rule in this state - if ((TERROR.toString()) in table[state]) { - break; - } - if (state == 0) { - throw new Error(errStr || 'Parsing halted.'); - } - popStack(1); - state = stack[stack.length-1]; - } - - preErrorSymbol = symbol; // save the lookahead token - symbol = TERROR; // insert generic error symbol as new lookahead - state = stack[stack.length-1]; - action = table[state] && table[state][TERROR]; - recovering = 3; // allow 3 real symbols to be shifted before reporting a new error - } - - // this shouldn't happen, unless resolve defaults are off - if (action[0] instanceof Array && action.length > 1) { - throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol); - } - - switch (action[0]) { - - case 1: // shift - //this.shiftCount++; - - stack.push(symbol); - vstack.push(this.lexer.yytext); - lstack.push(this.lexer.yylloc); - stack.push(action[1]); // push state - symbol = null; - if (!preErrorSymbol) { // normal execution/no error - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - if (recovering > 0) - recovering--; - } else { // error just occurred, resume old lookahead f/ before error - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - - case 2: // reduce - //this.reductionCount++; - - len = this.productions_[action[1]][1]; - - // perform semantic action - yyval.$ = vstack[vstack.length-len]; // default to $$ = $1 - // default location, uses first token for firsts, last for lasts - yyval._$ = { - first_line: lstack[lstack.length-(len||1)].first_line, - last_line: lstack[lstack.length-1].last_line, - first_column: lstack[lstack.length-(len||1)].first_column, - last_column: lstack[lstack.length-1].last_column - }; - r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); - - if (typeof r !== 'undefined') { - return r; - } - - // pop off stack - if (len) { - stack = stack.slice(0,-1*len*2); - vstack = vstack.slice(0, -1*len); - lstack = lstack.slice(0, -1*len); - } - - stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce) - vstack.push(yyval.$); - lstack.push(yyval._$); - // goto new state = table[STATE][NONTERMINAL] - newState = table[stack[stack.length-2]][stack[stack.length-1]]; - stack.push(newState); - break; - - case 3: // accept - return true; - } - - } - - return true; -}}; -return parser; -})(); -if (typeof require !== 'undefined' && typeof exports !== 'undefined') { -exports.parser = parser; -exports.parse = function () { return parser.parse.apply(parser, arguments); } -exports.main = function commonjsMain(args) { - if (!args[1]) - throw new Error('Usage: '+args[0]+' FILE'); - if (typeof process !== 'undefined') { - var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8"); - } else { - var cwd = require("file").path(require("file").cwd()); - var source = cwd.join(args[1]).read({charset: "utf-8"}); - } - return exports.parser.parse(source); -} -if (typeof module !== 'undefined' && require.main === module) { - exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); -} -} -};require['./scope'] = new function() { - var exports = this; - (function() { - var Scope, extend, last, _ref; - - _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; - - exports.Scope = Scope = (function() { - - Scope.root = null; - - function Scope(parent, expressions, method) { - this.parent = parent; - this.expressions = expressions; - this.method = method; - this.variables = [ - { - name: 'arguments', - type: 'arguments' - } - ]; - this.positions = {}; - if (!this.parent) Scope.root = this; - } - - Scope.prototype.add = function(name, type, immediate) { - if (this.shared && !immediate) return this.parent.add(name, type, immediate); - if (Object.prototype.hasOwnProperty.call(this.positions, name)) { - return this.variables[this.positions[name]].type = type; - } else { - return this.positions[name] = this.variables.push({ - name: name, - type: type - }) - 1; - } - }; - - Scope.prototype.find = function(name, options) { - if (this.check(name, options)) return true; - this.add(name, 'var'); - return false; - }; - - Scope.prototype.parameter = function(name) { - if (this.shared && this.parent.check(name, true)) return; - return this.add(name, 'param'); - }; - - Scope.prototype.check = function(name, immediate) { - var found, _ref2; - found = !!this.type(name); - if (found || immediate) return found; - return !!((_ref2 = this.parent) != null ? _ref2.check(name) : void 0); - }; - - Scope.prototype.temporary = function(name, index) { - if (name.length > 1) { - return '_' + name + (index > 1 ? index : ''); - } else { - return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a'); - } - }; - - Scope.prototype.type = function(name) { - var v, _i, _len, _ref2; - _ref2 = this.variables; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - v = _ref2[_i]; - if (v.name === name) return v.type; - } - return null; - }; - - Scope.prototype.freeVariable = function(name, reserve) { - var index, temp; - if (reserve == null) reserve = true; - index = 0; - while (this.check((temp = this.temporary(name, index)))) { - index++; - } - if (reserve) this.add(temp, 'var', true); - return temp; - }; - - Scope.prototype.assign = function(name, value) { - this.add(name, { - value: value, - assigned: true - }, true); - return this.hasAssignments = true; - }; - - Scope.prototype.hasDeclarations = function() { - return !!this.declaredVariables().length; - }; - - Scope.prototype.declaredVariables = function() { - var realVars, tempVars, v, _i, _len, _ref2; - realVars = []; - tempVars = []; - _ref2 = this.variables; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - v = _ref2[_i]; - if (v.type === 'var') { - (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name); - } - } - return realVars.sort().concat(tempVars.sort()); - }; - - Scope.prototype.assignedVariables = function() { - var v, _i, _len, _ref2, _results; - _ref2 = this.variables; - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - v = _ref2[_i]; - if (v.type.assigned) _results.push("" + v.name + " = " + v.type.value); - } - return _results; - }; - - return Scope; - - })(); - -}).call(this); - -};require['./nodes'] = new function() { - var exports = this; - (function() { - var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref, - __hasProp = Object.prototype.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, - __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Scope = require('./scope').Scope; - - RESERVED = require('./lexer').RESERVED; - - _ref = require('./helpers'), compact = _ref.compact, flatten = _ref.flatten, extend = _ref.extend, merge = _ref.merge, del = _ref.del, starts = _ref.starts, ends = _ref.ends, last = _ref.last; - - exports.extend = extend; - - YES = function() { - return true; - }; - - NO = function() { - return false; - }; - - THIS = function() { - return this; - }; - - NEGATE = function() { - this.negated = !this.negated; - return this; - }; - - exports.Base = Base = (function() { - - function Base() {} - - Base.prototype.compile = function(o, lvl) { - var node; - o = extend({}, o); - if (lvl) o.level = lvl; - node = this.unfoldSoak(o) || this; - node.tab = o.indent; - if (o.level === LEVEL_TOP || !node.isStatement(o)) { - return node.compileNode(o); - } else { - return node.compileClosure(o); - } - }; - - Base.prototype.compileClosure = function(o) { - if (this.jumps()) { - throw SyntaxError('cannot use a pure statement in an expression.'); - } - o.sharedScope = true; - return Closure.wrap(this).compileNode(o); - }; - - Base.prototype.cache = function(o, level, reused) { - var ref, sub; - if (!this.isComplex()) { - ref = level ? this.compile(o, level) : this; - return [ref, ref]; - } else { - ref = new Literal(reused || o.scope.freeVariable('ref')); - sub = new Assign(ref, this); - if (level) { - return [sub.compile(o, level), ref.value]; - } else { - return [sub, ref]; - } - } - }; - - Base.prototype.compileLoopReference = function(o, name) { - var src, tmp; - src = tmp = this.compile(o, LEVEL_LIST); - if (!((-Infinity < +src && +src < Infinity) || IDENTIFIER.test(src) && o.scope.check(src, true))) { - src = "" + (tmp = o.scope.freeVariable(name)) + " = " + src; - } - return [src, tmp]; - }; - - Base.prototype.makeReturn = function(res) { - var me; - me = this.unwrapAll(); - if (res) { - return new Call(new Literal("" + res + ".push"), [me]); - } else { - return new Return(me); - } - }; - - Base.prototype.contains = function(pred) { - var contains; - contains = false; - this.traverseChildren(false, function(node) { - if (pred(node)) { - contains = true; - return false; - } - }); - return contains; - }; - - Base.prototype.containsType = function(type) { - return this instanceof type || this.contains(function(node) { - return node instanceof type; - }); - }; - - Base.prototype.lastNonComment = function(list) { - var i; - i = list.length; - while (i--) { - if (!(list[i] instanceof Comment)) return list[i]; - } - return null; - }; - - Base.prototype.toString = function(idt, name) { - var tree; - if (idt == null) idt = ''; - if (name == null) name = this.constructor.name; - tree = '\n' + idt + name; - if (this.soak) tree += '?'; - this.eachChild(function(node) { - return tree += node.toString(idt + TAB); - }); - return tree; - }; - - Base.prototype.eachChild = function(func) { - var attr, child, _i, _j, _len, _len2, _ref2, _ref3; - if (!this.children) return this; - _ref2 = this.children; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - attr = _ref2[_i]; - if (this[attr]) { - _ref3 = flatten([this[attr]]); - for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { - child = _ref3[_j]; - if (func(child) === false) return this; - } - } - } - return this; - }; - - Base.prototype.traverseChildren = function(crossScope, func) { - return this.eachChild(function(child) { - if (func(child) === false) return false; - return child.traverseChildren(crossScope, func); - }); - }; - - Base.prototype.invert = function() { - return new Op('!', this); - }; - - Base.prototype.unwrapAll = function() { - var node; - node = this; - while (node !== (node = node.unwrap())) { - continue; - } - return node; - }; - - Base.prototype.children = []; - - Base.prototype.isStatement = NO; - - Base.prototype.jumps = NO; - - Base.prototype.isComplex = YES; - - Base.prototype.isChainable = NO; - - Base.prototype.isAssignable = NO; - - Base.prototype.unwrap = THIS; - - Base.prototype.unfoldSoak = NO; - - Base.prototype.assigns = NO; - - return Base; - - })(); - - exports.Block = Block = (function(_super) { - - __extends(Block, _super); - - function Block(nodes) { - this.expressions = compact(flatten(nodes || [])); - } - - Block.prototype.children = ['expressions']; - - Block.prototype.push = function(node) { - this.expressions.push(node); - return this; - }; - - Block.prototype.pop = function() { - return this.expressions.pop(); - }; - - Block.prototype.unshift = function(node) { - this.expressions.unshift(node); - return this; - }; - - Block.prototype.unwrap = function() { - if (this.expressions.length === 1) { - return this.expressions[0]; - } else { - return this; - } - }; - - Block.prototype.isEmpty = function() { - return !this.expressions.length; - }; - - Block.prototype.isStatement = function(o) { - var exp, _i, _len, _ref2; - _ref2 = this.expressions; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - exp = _ref2[_i]; - if (exp.isStatement(o)) return true; - } - return false; - }; - - Block.prototype.jumps = function(o) { - var exp, _i, _len, _ref2; - _ref2 = this.expressions; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - exp = _ref2[_i]; - if (exp.jumps(o)) return exp; - } - }; - - Block.prototype.makeReturn = function(res) { - var expr, len; - len = this.expressions.length; - while (len--) { - expr = this.expressions[len]; - if (!(expr instanceof Comment)) { - this.expressions[len] = expr.makeReturn(res); - if (expr instanceof Return && !expr.expression) { - this.expressions.splice(len, 1); - } - break; - } - } - return this; - }; - - Block.prototype.compile = function(o, level) { - if (o == null) o = {}; - if (o.scope) { - return Block.__super__.compile.call(this, o, level); - } else { - return this.compileRoot(o); - } - }; - - Block.prototype.compileNode = function(o) { - var code, codes, node, top, _i, _len, _ref2; - this.tab = o.indent; - top = o.level === LEVEL_TOP; - codes = []; - _ref2 = this.expressions; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - node = _ref2[_i]; - node = node.unwrapAll(); - node = node.unfoldSoak(o) || node; - if (node instanceof Block) { - codes.push(node.compileNode(o)); - } else if (top) { - node.front = true; - code = node.compile(o); - codes.push(node.isStatement(o) ? code : "" + this.tab + code + ";"); - } else { - codes.push(node.compile(o, LEVEL_LIST)); - } - } - if (top) { - if (this.spaced) { - return "\n" + (codes.join('\n\n')) + "\n"; - } else { - return codes.join('\n'); - } - } - code = codes.join(', ') || 'void 0'; - if (codes.length > 1 && o.level >= LEVEL_LIST) { - return "(" + code + ")"; - } else { - return code; - } - }; - - Block.prototype.compileRoot = function(o) { - var code, exp, i, prelude, preludeExps, rest; - o.indent = o.bare ? '' : TAB; - o.scope = new Scope(null, this, null); - o.level = LEVEL_TOP; - this.spaced = true; - prelude = ""; - if (!o.bare) { - preludeExps = (function() { - var _len, _ref2, _results; - _ref2 = this.expressions; - _results = []; - for (i = 0, _len = _ref2.length; i < _len; i++) { - exp = _ref2[i]; - if (!(exp.unwrap() instanceof Comment)) break; - _results.push(exp); - } - return _results; - }).call(this); - rest = this.expressions.slice(preludeExps.length); - this.expressions = preludeExps; - if (preludeExps.length) { - prelude = "" + (this.compileNode(merge(o, { - indent: '' - }))) + "\n"; - } - this.expressions = rest; - } - code = this.compileWithDeclarations(o); - if (o.bare) return code; - return "" + prelude + "(function() {\n" + code + "\n}).call(this);\n"; - }; - - Block.prototype.compileWithDeclarations = function(o) { - var assigns, code, declars, exp, i, post, rest, scope, spaced, _len, _ref2, _ref3, _ref4; - code = post = ''; - _ref2 = this.expressions; - for (i = 0, _len = _ref2.length; i < _len; i++) { - exp = _ref2[i]; - exp = exp.unwrap(); - if (!(exp instanceof Comment || exp instanceof Literal)) break; - } - o = merge(o, { - level: LEVEL_TOP - }); - if (i) { - rest = this.expressions.splice(i, 9e9); - _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1]; - _ref4 = [this.compileNode(o), spaced], code = _ref4[0], this.spaced = _ref4[1]; - this.expressions = rest; - } - post = this.compileNode(o); - scope = o.scope; - if (scope.expressions === this) { - declars = o.scope.hasDeclarations(); - assigns = scope.hasAssignments; - if (declars || assigns) { - if (i) code += '\n'; - code += "" + this.tab + "var "; - if (declars) code += scope.declaredVariables().join(', '); - if (assigns) { - if (declars) code += ",\n" + (this.tab + TAB); - code += scope.assignedVariables().join(",\n" + (this.tab + TAB)); - } - code += ';\n'; - } - } - return code + post; - }; - - Block.wrap = function(nodes) { - if (nodes.length === 1 && nodes[0] instanceof Block) return nodes[0]; - return new Block(nodes); - }; - - return Block; - - })(Base); - - exports.Literal = Literal = (function(_super) { - - __extends(Literal, _super); - - function Literal(value) { - this.value = value; - } - - Literal.prototype.makeReturn = function() { - if (this.isStatement()) { - return this; - } else { - return Literal.__super__.makeReturn.apply(this, arguments); - } - }; - - Literal.prototype.isAssignable = function() { - return IDENTIFIER.test(this.value); - }; - - Literal.prototype.isStatement = function() { - var _ref2; - return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger'; - }; - - Literal.prototype.isComplex = NO; - - Literal.prototype.assigns = function(name) { - return name === this.value; - }; - - Literal.prototype.jumps = function(o) { - if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) { - return this; - } - if (this.value === 'continue' && !(o != null ? o.loop : void 0)) return this; - }; - - Literal.prototype.compileNode = function(o) { - var code, _ref2, _ref3; - code = this.isUndefined ? o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0' : this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved && ((_ref3 = "" + this.value) !== 'eval' && _ref3 !== 'arguments') ? "\"" + this.value + "\"" : this.value; - if (this.isStatement()) { - return "" + this.tab + code + ";"; - } else { - return code; - } - }; - - Literal.prototype.toString = function() { - return ' "' + this.value + '"'; - }; - - return Literal; - - })(Base); - - exports.Return = Return = (function(_super) { - - __extends(Return, _super); - - function Return(expr) { - if (expr && !expr.unwrap().isUndefined) this.expression = expr; - } - - Return.prototype.children = ['expression']; - - Return.prototype.isStatement = YES; - - Return.prototype.makeReturn = THIS; - - Return.prototype.jumps = THIS; - - Return.prototype.compile = function(o, level) { - var expr, _ref2; - expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0; - if (expr && !(expr instanceof Return)) { - return expr.compile(o, level); - } else { - return Return.__super__.compile.call(this, o, level); - } - }; - - Return.prototype.compileNode = function(o) { - return this.tab + ("return" + [this.expression ? " " + (this.expression.compile(o, LEVEL_PAREN)) : void 0] + ";"); - }; - - return Return; - - })(Base); - - exports.Value = Value = (function(_super) { - - __extends(Value, _super); - - function Value(base, props, tag) { - if (!props && base instanceof Value) return base; - this.base = base; - this.properties = props || []; - if (tag) this[tag] = true; - return this; - } - - Value.prototype.children = ['base', 'properties']; - - Value.prototype.add = function(props) { - this.properties = this.properties.concat(props); - return this; - }; - - Value.prototype.hasProperties = function() { - return !!this.properties.length; - }; - - Value.prototype.isArray = function() { - return !this.properties.length && this.base instanceof Arr; - }; - - Value.prototype.isComplex = function() { - return this.hasProperties() || this.base.isComplex(); - }; - - Value.prototype.isAssignable = function() { - return this.hasProperties() || this.base.isAssignable(); - }; - - Value.prototype.isSimpleNumber = function() { - return this.base instanceof Literal && SIMPLENUM.test(this.base.value); - }; - - Value.prototype.isAtomic = function() { - var node, _i, _len, _ref2; - _ref2 = this.properties.concat(this.base); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - node = _ref2[_i]; - if (node.soak || node instanceof Call) return false; - } - return true; - }; - - Value.prototype.isStatement = function(o) { - return !this.properties.length && this.base.isStatement(o); - }; - - Value.prototype.assigns = function(name) { - return !this.properties.length && this.base.assigns(name); - }; - - Value.prototype.jumps = function(o) { - return !this.properties.length && this.base.jumps(o); - }; - - Value.prototype.isObject = function(onlyGenerated) { - if (this.properties.length) return false; - return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated); - }; - - Value.prototype.isSplice = function() { - return last(this.properties) instanceof Slice; - }; - - Value.prototype.unwrap = function() { - if (this.properties.length) { - return this; - } else { - return this.base; - } - }; - - Value.prototype.cacheReference = function(o) { - var base, bref, name, nref; - name = last(this.properties); - if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) { - return [this, this]; - } - base = new Value(this.base, this.properties.slice(0, -1)); - if (base.isComplex()) { - bref = new Literal(o.scope.freeVariable('base')); - base = new Value(new Parens(new Assign(bref, base))); - } - if (!name) return [base, bref]; - if (name.isComplex()) { - nref = new Literal(o.scope.freeVariable('name')); - name = new Index(new Assign(nref, name.index)); - nref = new Index(nref); - } - return [base.add(name), new Value(bref || base.base, [nref || name])]; - }; - - Value.prototype.compileNode = function(o) { - var code, prop, props, _i, _len; - this.base.front = this.front; - props = this.properties; - code = this.base.compile(o, props.length ? LEVEL_ACCESS : null); - if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(code)) { - code = "" + code + "."; - } - for (_i = 0, _len = props.length; _i < _len; _i++) { - prop = props[_i]; - code += prop.compile(o); - } - return code; - }; - - Value.prototype.unfoldSoak = function(o) { - var result, - _this = this; - if (this.unfoldedSoak != null) return this.unfoldedSoak; - result = (function() { - var fst, i, ifn, prop, ref, snd, _len, _ref2; - if (ifn = _this.base.unfoldSoak(o)) { - Array.prototype.push.apply(ifn.body.properties, _this.properties); - return ifn; - } - _ref2 = _this.properties; - for (i = 0, _len = _ref2.length; i < _len; i++) { - prop = _ref2[i]; - if (!prop.soak) continue; - prop.soak = false; - fst = new Value(_this.base, _this.properties.slice(0, i)); - snd = new Value(_this.base, _this.properties.slice(i)); - if (fst.isComplex()) { - ref = new Literal(o.scope.freeVariable('ref')); - fst = new Parens(new Assign(ref, fst)); - snd.base = ref; - } - return new If(new Existence(fst), snd, { - soak: true - }); - } - return null; - })(); - return this.unfoldedSoak = result || false; - }; - - return Value; - - })(Base); - - exports.Comment = Comment = (function(_super) { - - __extends(Comment, _super); - - function Comment(comment) { - this.comment = comment; - } - - Comment.prototype.isStatement = YES; - - Comment.prototype.makeReturn = THIS; - - Comment.prototype.compileNode = function(o, level) { - var code; - code = '/*' + multident(this.comment, this.tab) + ("\n" + this.tab + "*/"); - if ((level || o.level) === LEVEL_TOP) code = o.indent + code; - return code; - }; - - return Comment; - - })(Base); - - exports.Call = Call = (function(_super) { - - __extends(Call, _super); - - function Call(variable, args, soak) { - this.args = args != null ? args : []; - this.soak = soak; - this.isNew = false; - this.isSuper = variable === 'super'; - this.variable = this.isSuper ? null : variable; - } - - Call.prototype.children = ['variable', 'args']; - - Call.prototype.newInstance = function() { - var base, _ref2; - base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable; - if (base instanceof Call && !base.isNew) { - base.newInstance(); - } else { - this.isNew = true; - } - return this; - }; - - Call.prototype.superReference = function(o) { - var accesses, method, name; - method = o.scope.method; - if (!method) throw SyntaxError('cannot call super outside of a function.'); - name = method.name; - if (name == null) { - throw SyntaxError('cannot call super on an anonymous function.'); - } - if (method.klass) { - accesses = [new Access(new Literal('__super__'))]; - if (method.static) accesses.push(new Access(new Literal('constructor'))); - accesses.push(new Access(new Literal(name))); - return (new Value(new Literal(method.klass), accesses)).compile(o); - } else { - return "" + name + ".__super__.constructor"; - } - }; - - Call.prototype.unfoldSoak = function(o) { - var call, ifn, left, list, rite, _i, _len, _ref2, _ref3; - if (this.soak) { - if (this.variable) { - if (ifn = unfoldSoak(o, this, 'variable')) return ifn; - _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1]; - } else { - left = new Literal(this.superReference(o)); - rite = new Value(left); - } - rite = new Call(rite, this.args); - rite.isNew = this.isNew; - left = new Literal("typeof " + (left.compile(o)) + " === \"function\""); - return new If(left, new Value(rite), { - soak: true - }); - } - call = this; - list = []; - while (true) { - if (call.variable instanceof Call) { - list.push(call); - call = call.variable; - continue; - } - if (!(call.variable instanceof Value)) break; - list.push(call); - if (!((call = call.variable.base) instanceof Call)) break; - } - _ref3 = list.reverse(); - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - call = _ref3[_i]; - if (ifn) { - if (call.variable instanceof Call) { - call.variable = ifn; - } else { - call.variable.base = ifn; - } - } - ifn = unfoldSoak(o, call, 'variable'); - } - return ifn; - }; - - Call.prototype.filterImplicitObjects = function(list) { - var node, nodes, obj, prop, properties, _i, _j, _len, _len2, _ref2; - nodes = []; - for (_i = 0, _len = list.length; _i < _len; _i++) { - node = list[_i]; - if (!((typeof node.isObject === "function" ? node.isObject() : void 0) && node.base.generated)) { - nodes.push(node); - continue; - } - obj = null; - _ref2 = node.base.properties; - for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { - prop = _ref2[_j]; - if (prop instanceof Assign || prop instanceof Comment) { - if (!obj) nodes.push(obj = new Obj(properties = [], true)); - properties.push(prop); - } else { - nodes.push(prop); - obj = null; - } - } - } - return nodes; - }; - - Call.prototype.compileNode = function(o) { - var arg, args, code, _ref2; - if ((_ref2 = this.variable) != null) _ref2.front = this.front; - if (code = Splat.compileSplattedArray(o, this.args, true)) { - return this.compileSplat(o, code); - } - args = this.filterImplicitObjects(this.args); - args = ((function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = args.length; _i < _len; _i++) { - arg = args[_i]; - _results.push(arg.compile(o, LEVEL_LIST)); - } - return _results; - })()).join(', '); - if (this.isSuper) { - return this.superReference(o) + (".call(this" + (args && ', ' + args) + ")"); - } else { - return (this.isNew ? 'new ' : '') + this.variable.compile(o, LEVEL_ACCESS) + ("(" + args + ")"); - } - }; - - Call.prototype.compileSuper = function(args, o) { - return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")"; - }; - - Call.prototype.compileSplat = function(o, splatArgs) { - var base, fun, idt, name, ref; - if (this.isSuper) { - return "" + (this.superReference(o)) + ".apply(this, " + splatArgs + ")"; - } - if (this.isNew) { - idt = this.tab + TAB; - return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return typeof result === \"object\" ? result : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function() {})"; - } - base = new Value(this.variable); - if ((name = base.properties.pop()) && base.isComplex()) { - ref = o.scope.freeVariable('ref'); - fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o)); - } else { - fun = base.compile(o, LEVEL_ACCESS); - if (SIMPLENUM.test(fun)) fun = "(" + fun + ")"; - if (name) { - ref = fun; - fun += name.compile(o); - } else { - ref = 'null'; - } - } - return "" + fun + ".apply(" + ref + ", " + splatArgs + ")"; - }; - - return Call; - - })(Base); - - exports.Extends = Extends = (function(_super) { - - __extends(Extends, _super); - - function Extends(child, parent) { - this.child = child; - this.parent = parent; - } - - Extends.prototype.children = ['child', 'parent']; - - Extends.prototype.compile = function(o) { - return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o); - }; - - return Extends; - - })(Base); - - exports.Access = Access = (function(_super) { - - __extends(Access, _super); - - function Access(name, tag) { - this.name = name; - this.name.asKey = true; - this.soak = tag === 'soak'; - } - - Access.prototype.children = ['name']; - - Access.prototype.compile = function(o) { - var name; - name = this.name.compile(o); - if (IDENTIFIER.test(name)) { - return "." + name; - } else { - return "[" + name + "]"; - } - }; - - Access.prototype.isComplex = NO; - - return Access; - - })(Base); - - exports.Index = Index = (function(_super) { - - __extends(Index, _super); - - function Index(index) { - this.index = index; - } - - Index.prototype.children = ['index']; - - Index.prototype.compile = function(o) { - return "[" + (this.index.compile(o, LEVEL_PAREN)) + "]"; - }; - - Index.prototype.isComplex = function() { - return this.index.isComplex(); - }; - - return Index; - - })(Base); - - exports.Range = Range = (function(_super) { - - __extends(Range, _super); - - Range.prototype.children = ['from', 'to']; - - function Range(from, to, tag) { - this.from = from; - this.to = to; - this.exclusive = tag === 'exclusive'; - this.equals = this.exclusive ? '' : '='; - } - - Range.prototype.compileVariables = function(o) { - var step, _ref2, _ref3, _ref4, _ref5; - o = merge(o, { - top: true - }); - _ref2 = this.from.cache(o, LEVEL_LIST), this.fromC = _ref2[0], this.fromVar = _ref2[1]; - _ref3 = this.to.cache(o, LEVEL_LIST), this.toC = _ref3[0], this.toVar = _ref3[1]; - if (step = del(o, 'step')) { - _ref4 = step.cache(o, LEVEL_LIST), this.step = _ref4[0], this.stepVar = _ref4[1]; - } - _ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1]; - if (this.stepVar) return this.stepNum = this.stepVar.match(SIMPLENUM); - }; - - Range.prototype.compileNode = function(o) { - var cond, condPart, from, gt, idx, known, lt, stepPart, to, varPart, _ref2, _ref3; - if (!this.fromVar) this.compileVariables(o); - if (!o.index) return this.compileArray(o); - known = this.fromNum && this.toNum; - idx = del(o, 'index'); - varPart = "" + idx + " = " + this.fromC; - if (this.toC !== this.toVar) varPart += ", " + this.toC; - if (this.step !== this.stepVar) varPart += ", " + this.step; - _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1]; - condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar); - stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? from <= to ? "" + idx + "++" : "" + idx + "--" : "" + cond + " ? " + idx + "++ : " + idx + "--"; - return "" + varPart + "; " + condPart + "; " + stepPart; - }; - - Range.prototype.compileArray = function(o) { - var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results; - if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) { - range = (function() { - _results = []; - for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); } - return _results; - }).apply(this); - if (this.exclusive) range.pop(); - return "[" + (range.join(', ')) + "]"; - } - idt = this.tab + TAB; - i = o.scope.freeVariable('i'); - result = o.scope.freeVariable('results'); - pre = "\n" + idt + result + " = [];"; - if (this.fromNum && this.toNum) { - o.index = i; - body = this.compileNode(o); - } else { - vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : ''); - cond = "" + this.fromVar + " <= " + this.toVar; - body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--"; - } - post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent; - hasArgs = function(node) { - return node != null ? node.contains(function(n) { - return n instanceof Literal && n.value === 'arguments' && !n.asKey; - }) : void 0; - }; - if (hasArgs(this.from) || hasArgs(this.to)) args = ', arguments'; - return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")"; - }; - - return Range; - - })(Base); - - exports.Slice = Slice = (function(_super) { - - __extends(Slice, _super); - - Slice.prototype.children = ['range']; - - function Slice(range) { - this.range = range; - Slice.__super__.constructor.call(this); - } - - Slice.prototype.compileNode = function(o) { - var compiled, from, fromStr, to, toStr, _ref2; - _ref2 = this.range, to = _ref2.to, from = _ref2.from; - fromStr = from && from.compile(o, LEVEL_PAREN) || '0'; - compiled = to && to.compile(o, LEVEL_ACCESS); - if (to && !(!this.range.exclusive && +compiled === -1)) { - toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? (+compiled + 1).toString() : "" + compiled + " + 1 || 9e9"); - } - return ".slice(" + fromStr + (toStr || '') + ")"; - }; - - return Slice; - - })(Base); - - exports.Obj = Obj = (function(_super) { - - __extends(Obj, _super); - - function Obj(props, generated) { - this.generated = generated != null ? generated : false; - this.objects = this.properties = props || []; - } - - Obj.prototype.children = ['properties']; - - Obj.prototype.compileNode = function(o) { - var i, idt, indent, join, lastNoncom, node, obj, prop, props, _i, _len; - props = this.properties; - if (!props.length) return (this.front ? '({})' : '{}'); - if (this.generated) { - for (_i = 0, _len = props.length; _i < _len; _i++) { - node = props[_i]; - if (node instanceof Value) { - throw new Error('cannot have an implicit value in an implicit object'); - } - } - } - idt = o.indent += TAB; - lastNoncom = this.lastNonComment(this.properties); - props = (function() { - var _len2, _results; - _results = []; - for (i = 0, _len2 = props.length; i < _len2; i++) { - prop = props[i]; - join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; - indent = prop instanceof Comment ? '' : idt; - if (prop instanceof Value && prop["this"]) { - prop = new Assign(prop.properties[0].name, prop, 'object'); - } - if (!(prop instanceof Comment)) { - if (!(prop instanceof Assign)) prop = new Assign(prop, prop, 'object'); - (prop.variable.base || prop.variable).asKey = true; - } - _results.push(indent + prop.compile(o, LEVEL_TOP) + join); - } - return _results; - })(); - props = props.join(''); - obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}"; - if (this.front) { - return "(" + obj + ")"; - } else { - return obj; - } - }; - - Obj.prototype.assigns = function(name) { - var prop, _i, _len, _ref2; - _ref2 = this.properties; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - prop = _ref2[_i]; - if (prop.assigns(name)) return true; - } - return false; - }; - - return Obj; - - })(Base); - - exports.Arr = Arr = (function(_super) { - - __extends(Arr, _super); - - function Arr(objs) { - this.objects = objs || []; - } - - Arr.prototype.children = ['objects']; - - Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects; - - Arr.prototype.compileNode = function(o) { - var code, obj, objs; - if (!this.objects.length) return '[]'; - o.indent += TAB; - objs = this.filterImplicitObjects(this.objects); - if (code = Splat.compileSplattedArray(o, objs)) return code; - code = ((function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = objs.length; _i < _len; _i++) { - obj = objs[_i]; - _results.push(obj.compile(o, LEVEL_LIST)); - } - return _results; - })()).join(', '); - if (code.indexOf('\n') >= 0) { - return "[\n" + o.indent + code + "\n" + this.tab + "]"; - } else { - return "[" + code + "]"; - } - }; - - Arr.prototype.assigns = function(name) { - var obj, _i, _len, _ref2; - _ref2 = this.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; - if (obj.assigns(name)) return true; - } - return false; - }; - - return Arr; - - })(Base); - - exports.Class = Class = (function(_super) { - - __extends(Class, _super); - - function Class(variable, parent, body) { - this.variable = variable; - this.parent = parent; - this.body = body != null ? body : new Block; - this.boundFuncs = []; - this.body.classBody = true; - } - - Class.prototype.children = ['variable', 'parent', 'body']; - - Class.prototype.determineName = function() { - var decl, tail; - if (!this.variable) return null; - decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value; - return decl && (decl = IDENTIFIER.test(decl) && decl); - }; - - Class.prototype.setContext = function(name) { - return this.body.traverseChildren(false, function(node) { - if (node.classBody) return false; - if (node instanceof Literal && node.value === 'this') { - return node.value = name; - } else if (node instanceof Code) { - node.klass = name; - if (node.bound) return node.context = name; - } - }); - }; - - Class.prototype.addBoundFunctions = function(o) { - var bvar, lhs, _i, _len, _ref2, _results; - if (this.boundFuncs.length) { - _ref2 = this.boundFuncs; - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - bvar = _ref2[_i]; - lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o); - _results.push(this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"))); - } - return _results; - } - }; - - Class.prototype.addProperties = function(node, name, o) { - var assign, base, exprs, func, props; - props = node.base.properties.slice(0); - exprs = (function() { - var _results; - _results = []; - while (assign = props.shift()) { - if (assign instanceof Assign) { - base = assign.variable.base; - delete assign.context; - func = assign.value; - if (base.value === 'constructor') { - if (this.ctor) { - throw new Error('cannot define more than one constructor in a class'); - } - if (func.bound) { - throw new Error('cannot define a constructor as a bound function'); - } - if (func instanceof Code) { - assign = this.ctor = func; - } else { - this.externalCtor = o.scope.freeVariable('class'); - assign = new Assign(new Literal(this.externalCtor), func); - } - } else { - if (assign.variable["this"]) { - func.static = true; - if (func.bound) func.context = name; - } else { - assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]); - if (func instanceof Code && func.bound) { - this.boundFuncs.push(base); - func.bound = false; - } - } - } - } - _results.push(assign); - } - return _results; - }).call(this); - return compact(exprs); - }; - - Class.prototype.walkBody = function(name, o) { - var _this = this; - return this.traverseChildren(false, function(child) { - var exps, i, node, _len, _ref2; - if (child instanceof Class) return false; - if (child instanceof Block) { - _ref2 = exps = child.expressions; - for (i = 0, _len = _ref2.length; i < _len; i++) { - node = _ref2[i]; - if (node instanceof Value && node.isObject(true)) { - exps[i] = _this.addProperties(node, name, o); - } - } - return child.expressions = exps = flatten(exps); - } - }); - }; - - Class.prototype.ensureConstructor = function(name) { - if (!this.ctor) { - this.ctor = new Code; - if (this.parent) { - this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)")); - } - if (this.externalCtor) { - this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)")); - } - this.body.expressions.unshift(this.ctor); - } - this.ctor.ctor = this.ctor.name = name; - this.ctor.klass = null; - return this.ctor.noReturn = true; - }; - - Class.prototype.compileNode = function(o) { - var call, decl, klass, lname, name; - decl = this.determineName(); - name = decl || this.name || '_Class'; - if (name.reserved) name = "_" + name; - lname = new Literal(name); - this.setContext(name); - this.walkBody(name, o); - this.ensureConstructor(name); - this.body.spaced = true; - if (!(this.ctor instanceof Code)) this.body.expressions.unshift(this.ctor); - this.body.expressions.push(lname); - this.addBoundFunctions(o); - call = Closure.wrap(this.body); - if (this.parent) { - this.superClass = new Literal(o.scope.freeVariable('super', false)); - this.body.expressions.unshift(new Extends(lname, this.superClass)); - call.args.push(this.parent); - call.variable.params.push(new Param(this.superClass)); - } - klass = new Parens(call, true); - if (this.variable) klass = new Assign(this.variable, klass); - return klass.compile(o); - }; - - return Class; - - })(Base); - - exports.Assign = Assign = (function(_super) { - - __extends(Assign, _super); - - function Assign(variable, value, context, options) { - this.variable = variable; - this.value = value; - this.context = context; - this.param = options && options.param; - this.subpattern = options && options.subpattern; - } - - Assign.prototype.children = ['variable', 'value']; - - Assign.prototype.isStatement = function(o) { - return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0; - }; - - Assign.prototype.assigns = function(name) { - return this[this.context === 'object' ? 'value' : 'variable'].assigns(name); - }; - - Assign.prototype.unfoldSoak = function(o) { - return unfoldSoak(o, this, 'variable'); - }; - - Assign.prototype.compileNode = function(o) { - var isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5; - if (isValue = this.variable instanceof Value) { - if (this.variable.isArray() || this.variable.isObject()) { - return this.compilePatternMatch(o); - } - if (this.variable.isSplice()) return this.compileSplice(o); - if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') { - return this.compileConditional(o); - } - } - name = this.variable.compile(o, LEVEL_LIST); - if (!this.context) { - if (!(varBase = this.variable.unwrapAll()).isAssignable()) { - throw SyntaxError("\"" + (this.variable.compile(o)) + "\" cannot be assigned."); - } - if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) { - if (this.param) { - o.scope.add(name, 'var'); - } else { - o.scope.find(name); - } - } - } - if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) { - if (match[1]) this.value.klass = match[1]; - this.value.name = (_ref3 = (_ref4 = (_ref5 = match[2]) != null ? _ref5 : match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5]; - } - val = this.value.compile(o, LEVEL_LIST); - if (this.context === 'object') return "" + name + ": " + val; - val = name + (" " + (this.context || '=') + " ") + val; - if (o.level <= LEVEL_LIST) { - return val; - } else { - return "(" + val + ")"; - } - }; - - Assign.prototype.compilePatternMatch = function(o) { - var acc, assigns, code, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; - top = o.level === LEVEL_TOP; - value = this.value; - objects = this.variable.base.objects; - if (!(olen = objects.length)) { - code = value.compile(o); - if (o.level >= LEVEL_OP) { - return "(" + code + ")"; - } else { - return code; - } - } - isObject = this.variable.isObject(); - if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) { - if (obj instanceof Assign) { - _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value; - } else { - if (obj.base instanceof Parens) { - _ref4 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1]; - } else { - idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0); - } - } - acc = IDENTIFIER.test(idx.unwrap().value || 0); - value = new Value(value); - value.properties.push(new (acc ? Access : Index)(idx)); - if (_ref5 = obj.unwrap().value, __indexOf.call(['arguments', 'eval'].concat(RESERVED), _ref5) >= 0) { - throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o))); - } - return new Assign(obj, value, null, { - param: this.param - }).compile(o, LEVEL_TOP); - } - vvar = value.compile(o, LEVEL_LIST); - assigns = []; - splat = false; - if (!IDENTIFIER.test(vvar) || this.variable.assigns(vvar)) { - assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + vvar); - vvar = ref; - } - for (i = 0, _len = objects.length; i < _len; i++) { - obj = objects[i]; - idx = i; - if (isObject) { - if (obj instanceof Assign) { - _ref6 = obj, (_ref7 = _ref6.variable, idx = _ref7.base), obj = _ref6.value; - } else { - if (obj.base instanceof Parens) { - _ref8 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1]; - } else { - idx = obj["this"] ? obj.properties[0].name : obj; - } - } - } - if (!splat && obj instanceof Splat) { - name = obj.name.unwrap().value; - obj = obj.unwrap(); - val = "" + olen + " <= " + vvar + ".length ? " + (utility('slice')) + ".call(" + vvar + ", " + i; - if (rest = olen - i - 1) { - ivar = o.scope.freeVariable('i'); - val += ", " + ivar + " = " + vvar + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])"; - } else { - val += ") : []"; - } - val = new Literal(val); - splat = "" + ivar + "++"; - } else { - name = obj.unwrap().value; - if (obj instanceof Splat) { - obj = obj.name.compile(o); - throw new SyntaxError("multiple splats are disallowed in an assignment: " + obj + "..."); - } - if (typeof idx === 'number') { - idx = new Literal(splat || idx); - acc = false; - } else { - acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0); - } - val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]); - } - if ((name != null) && __indexOf.call(['arguments', 'eval'].concat(RESERVED), name) >= 0) { - throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o))); - } - assigns.push(new Assign(obj, val, null, { - param: this.param, - subpattern: true - }).compile(o, LEVEL_LIST)); - } - if (!(top || this.subpattern)) assigns.push(vvar); - code = assigns.join(', '); - if (o.level < LEVEL_LIST) { - return code; - } else { - return "(" + code + ")"; - } - }; - - Assign.prototype.compileConditional = function(o) { - var left, rite, _ref2; - _ref2 = this.variable.cacheReference(o), left = _ref2[0], rite = _ref2[1]; - if (__indexOf.call(this.context, "?") >= 0) o.isExistentialEquals = true; - return new Op(this.context.slice(0, -1), left, new Assign(rite, this.value, '=')).compile(o); - }; - - Assign.prototype.compileSplice = function(o) { - var code, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4; - _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive; - name = this.variable.compile(o); - _ref3 = (from != null ? from.cache(o, LEVEL_OP) : void 0) || ['0', '0'], fromDecl = _ref3[0], fromRef = _ref3[1]; - if (to) { - if ((from != null ? from.isSimpleNumber() : void 0) && to.isSimpleNumber()) { - to = +to.compile(o) - +fromRef; - if (!exclusive) to += 1; - } else { - to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef; - if (!exclusive) to += ' + 1'; - } - } else { - to = "9e9"; - } - _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1]; - code = "[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat(" + valDef + ")), " + valRef; - if (o.level > LEVEL_TOP) { - return "(" + code + ")"; - } else { - return code; - } - }; - - return Assign; - - })(Base); - - exports.Code = Code = (function(_super) { - - __extends(Code, _super); - - function Code(params, body, tag) { - this.params = params || []; - this.body = body || new Block; - this.bound = tag === 'boundfunc'; - if (this.bound) this.context = '_this'; - } - - Code.prototype.children = ['params', 'body']; - - Code.prototype.isStatement = function() { - return !!this.ctor; - }; - - Code.prototype.jumps = NO; - - Code.prototype.compileNode = function(o) { - var code, exprs, i, idt, lit, p, param, ref, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4, _ref5, _ref6; - o.scope = new Scope(o.scope, this.body, this); - o.scope.shared = del(o, 'sharedScope'); - o.indent += TAB; - delete o.bare; - vars = []; - exprs = []; - _ref2 = this.params; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - param = _ref2[_i]; - if (!param.splat) continue; - _ref3 = this.params; - for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { - p = _ref3[_j]; - if (p.name.value) o.scope.add(p.name.value, 'var', true); - } - splats = new Assign(new Value(new Arr((function() { - var _k, _len3, _ref4, _results; - _ref4 = this.params; - _results = []; - for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { - p = _ref4[_k]; - _results.push(p.asReference(o)); - } - return _results; - }).call(this))), new Value(new Literal('arguments'))); - break; - } - _ref4 = this.params; - for (_k = 0, _len3 = _ref4.length; _k < _len3; _k++) { - param = _ref4[_k]; - if (param.isComplex()) { - val = ref = param.asReference(o); - if (param.value) val = new Op('?', ref, param.value); - exprs.push(new Assign(new Value(param.name), val, '=', { - param: true - })); - } else { - ref = param; - if (param.value) { - lit = new Literal(ref.name.value + ' == null'); - val = new Assign(new Value(param.name), param.value, '='); - exprs.push(new If(lit, val)); - } - } - if (!splats) vars.push(ref); - } - wasEmpty = this.body.isEmpty(); - if (splats) exprs.unshift(splats); - if (exprs.length) { - (_ref5 = this.body.expressions).unshift.apply(_ref5, exprs); - } - if (!splats) { - for (i = 0, _len4 = vars.length; i < _len4; i++) { - v = vars[i]; - o.scope.parameter(vars[i] = v.compile(o)); - } - } - if (!(wasEmpty || this.noReturn)) this.body.makeReturn(); - if (this.bound) { - if ((_ref6 = o.scope.parent.method) != null ? _ref6.bound : void 0) { - this.bound = this.context = o.scope.parent.method.context; - } else if (!this.static) { - o.scope.parent.assign('_this', 'this'); - } - } - idt = o.indent; - code = 'function'; - if (this.ctor) code += ' ' + this.name; - code += '(' + vars.join(', ') + ') {'; - if (!this.body.isEmpty()) { - code += "\n" + (this.body.compileWithDeclarations(o)) + "\n" + this.tab; - } - code += '}'; - if (this.ctor) return this.tab + code; - if (this.front || (o.level >= LEVEL_ACCESS)) { - return "(" + code + ")"; - } else { - return code; - } - }; - - Code.prototype.traverseChildren = function(crossScope, func) { - if (crossScope) { - return Code.__super__.traverseChildren.call(this, crossScope, func); - } - }; - - return Code; - - })(Base); - - exports.Param = Param = (function(_super) { - - __extends(Param, _super); - - function Param(name, value, splat) { - this.name = name; - this.value = value; - this.splat = splat; - } - - Param.prototype.children = ['name', 'value']; - - Param.prototype.compile = function(o) { - return this.name.compile(o, LEVEL_LIST); - }; - - Param.prototype.asReference = function(o) { - var node; - if (this.reference) return this.reference; - node = this.name; - if (node["this"]) { - node = node.properties[0].name; - if (node.value.reserved) node = new Literal('_' + node.value); - } else if (node.isComplex()) { - node = new Literal(o.scope.freeVariable('arg')); - } - node = new Value(node); - if (this.splat) node = new Splat(node); - return this.reference = node; - }; - - Param.prototype.isComplex = function() { - return this.name.isComplex(); - }; - - return Param; - - })(Base); - - exports.Splat = Splat = (function(_super) { - - __extends(Splat, _super); - - Splat.prototype.children = ['name']; - - Splat.prototype.isAssignable = YES; - - function Splat(name) { - this.name = name.compile ? name : new Literal(name); - } - - Splat.prototype.assigns = function(name) { - return this.name.assigns(name); - }; - - Splat.prototype.compile = function(o) { - if (this.index != null) { - return this.compileParam(o); - } else { - return this.name.compile(o); - } - }; - - Splat.prototype.unwrap = function() { - return this.name; - }; - - Splat.compileSplattedArray = function(o, list, apply) { - var args, base, code, i, index, node, _len; - index = -1; - while ((node = list[++index]) && !(node instanceof Splat)) { - continue; - } - if (index >= list.length) return ''; - if (list.length === 1) { - code = list[0].compile(o, LEVEL_LIST); - if (apply) return code; - return "" + (utility('slice')) + ".call(" + code + ")"; - } - args = list.slice(index); - for (i = 0, _len = args.length; i < _len; i++) { - node = args[i]; - code = node.compile(o, LEVEL_LIST); - args[i] = node instanceof Splat ? "" + (utility('slice')) + ".call(" + code + ")" : "[" + code + "]"; - } - if (index === 0) { - return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")"); - } - base = (function() { - var _i, _len2, _ref2, _results; - _ref2 = list.slice(0, index); - _results = []; - for (_i = 0, _len2 = _ref2.length; _i < _len2; _i++) { - node = _ref2[_i]; - _results.push(node.compile(o, LEVEL_LIST)); - } - return _results; - })(); - return "[" + (base.join(', ')) + "].concat(" + (args.join(', ')) + ")"; - }; - - return Splat; - - })(Base); - - exports.While = While = (function(_super) { - - __extends(While, _super); - - function While(condition, options) { - this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition; - this.guard = options != null ? options.guard : void 0; - } - - While.prototype.children = ['condition', 'guard', 'body']; - - While.prototype.isStatement = YES; - - While.prototype.makeReturn = function(res) { - if (res) { - return While.__super__.makeReturn.apply(this, arguments); - } else { - this.returns = !this.jumps({ - loop: true - }); - return this; - } - }; - - While.prototype.addBody = function(body) { - this.body = body; - return this; - }; - - While.prototype.jumps = function() { - var expressions, node, _i, _len; - expressions = this.body.expressions; - if (!expressions.length) return false; - for (_i = 0, _len = expressions.length; _i < _len; _i++) { - node = expressions[_i]; - if (node.jumps({ - loop: true - })) return node; - } - return false; - }; - - While.prototype.compileNode = function(o) { - var body, code, rvar, set; - o.indent += TAB; - set = ''; - body = this.body; - if (body.isEmpty()) { - body = ''; - } else { - if (this.returns) { - body.makeReturn(rvar = o.scope.freeVariable('results')); - set = "" + this.tab + rvar + " = [];\n"; - } - if (this.guard) { - if (body.expressions.length > 1) { - body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); - } else { - if (this.guard) body = Block.wrap([new If(this.guard, body)]); - } - } - body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab; - } - code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {" + body + "}"); - if (this.returns) code += "\n" + this.tab + "return " + rvar + ";"; - return code; - }; - - return While; - - })(Base); - - exports.Op = Op = (function(_super) { - var CONVERSIONS, INVERSIONS; - - __extends(Op, _super); - - function Op(op, first, second, flip) { - var call; - if (op === 'in') return new In(first, second); - if (op === 'do') { - call = new Call(first, first.params || []); - call["do"] = true; - return call; - } - if (op === 'new') { - if (first instanceof Call && !first["do"] && !first.isNew) { - return first.newInstance(); - } - if (first instanceof Code && first.bound || first["do"]) { - first = new Parens(first); - } - } - this.operator = CONVERSIONS[op] || op; - this.first = first; - this.second = second; - this.flip = !!flip; - return this; - } - - CONVERSIONS = { - '==': '===', - '!=': '!==', - 'of': 'in' - }; - - INVERSIONS = { - '!==': '===', - '===': '!==' - }; - - Op.prototype.children = ['first', 'second']; - - Op.prototype.isSimpleNumber = NO; - - Op.prototype.isUnary = function() { - return !this.second; - }; - - Op.prototype.isComplex = function() { - var _ref2; - return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex(); - }; - - Op.prototype.isChainable = function() { - var _ref2; - return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!=='; - }; - - Op.prototype.invert = function() { - var allInvertable, curr, fst, op, _ref2; - if (this.isChainable() && this.first.isChainable()) { - allInvertable = true; - curr = this; - while (curr && curr.operator) { - allInvertable && (allInvertable = curr.operator in INVERSIONS); - curr = curr.first; - } - if (!allInvertable) return new Parens(this).invert(); - curr = this; - while (curr && curr.operator) { - curr.invert = !curr.invert; - curr.operator = INVERSIONS[curr.operator]; - curr = curr.first; - } - return this; - } else if (op = INVERSIONS[this.operator]) { - this.operator = op; - if (this.first.unwrap() instanceof Op) this.first.invert(); - return this; - } else if (this.second) { - return new Parens(this).invert(); - } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) { - return fst; - } else { - return new Op('!', this); - } - }; - - Op.prototype.unfoldSoak = function(o) { - var _ref2; - return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first'); - }; - - Op.prototype.compileNode = function(o) { - var code, isChain; - isChain = this.isChainable() && this.first.isChainable(); - if (!isChain) this.first.front = this.front; - if (this.isUnary()) return this.compileUnary(o); - if (isChain) return this.compileChain(o); - if (this.operator === '?') return this.compileExistence(o); - code = this.first.compile(o, LEVEL_OP) + ' ' + this.operator + ' ' + this.second.compile(o, LEVEL_OP); - if (o.level <= LEVEL_OP) { - return code; - } else { - return "(" + code + ")"; - } - }; - - Op.prototype.compileChain = function(o) { - var code, fst, shared, _ref2; - _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1]; - fst = this.first.compile(o, LEVEL_OP); - code = "" + fst + " " + (this.invert ? '&&' : '||') + " " + (shared.compile(o)) + " " + this.operator + " " + (this.second.compile(o, LEVEL_OP)); - return "(" + code + ")"; - }; - - Op.prototype.compileExistence = function(o) { - var fst, ref; - if (this.first.isComplex() && o.level > LEVEL_TOP) { - ref = new Literal(o.scope.freeVariable('ref')); - fst = new Parens(new Assign(ref, this.first)); - } else { - fst = this.first; - ref = fst; - } - return new If(new Existence(fst), ref, { - type: 'if' - }).addElse(this.second).compile(o); - }; - - Op.prototype.compileUnary = function(o) { - var op, parts, plusMinus; - parts = [op = this.operator]; - plusMinus = op === '+' || op === '-'; - if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) { - parts.push(' '); - } - if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) { - this.first = new Parens(this.first); - } - parts.push(this.first.compile(o, LEVEL_OP)); - if (this.flip) parts.reverse(); - return parts.join(''); - }; - - Op.prototype.toString = function(idt) { - return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); - }; - - return Op; - - })(Base); - - exports.In = In = (function(_super) { - - __extends(In, _super); - - function In(object, array) { - this.object = object; - this.array = array; - } - - In.prototype.children = ['object', 'array']; - - In.prototype.invert = NEGATE; - - In.prototype.compileNode = function(o) { - var hasSplat, obj, _i, _len, _ref2; - if (this.array instanceof Value && this.array.isArray()) { - _ref2 = this.array.base.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; - if (!(obj instanceof Splat)) continue; - hasSplat = true; - break; - } - if (!hasSplat) return this.compileOrTest(o); - } - return this.compileLoopTest(o); - }; - - In.prototype.compileOrTest = function(o) { - var cmp, cnj, i, item, ref, sub, tests, _ref2, _ref3; - if (this.array.base.objects.length === 0) return "" + (!!this.negated); - _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1]; - _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1]; - tests = (function() { - var _len, _ref4, _results; - _ref4 = this.array.base.objects; - _results = []; - for (i = 0, _len = _ref4.length; i < _len; i++) { - item = _ref4[i]; - _results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_ACCESS)); - } - return _results; - }).call(this); - tests = tests.join(cnj); - if (o.level < LEVEL_OP) { - return tests; - } else { - return "(" + tests + ")"; - } - }; - - In.prototype.compileLoopTest = function(o) { - var code, ref, sub, _ref2; - _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1]; - code = utility('indexOf') + (".call(" + (this.array.compile(o, LEVEL_LIST)) + ", " + ref + ") ") + (this.negated ? '< 0' : '>= 0'); - if (sub === ref) return code; - code = sub + ', ' + code; - if (o.level < LEVEL_LIST) { - return code; - } else { - return "(" + code + ")"; - } - }; - - In.prototype.toString = function(idt) { - return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : '')); - }; - - return In; - - })(Base); - - exports.Try = Try = (function(_super) { - - __extends(Try, _super); - - function Try(attempt, error, recovery, ensure) { - this.attempt = attempt; - this.error = error; - this.recovery = recovery; - this.ensure = ensure; - } - - Try.prototype.children = ['attempt', 'recovery', 'ensure']; - - Try.prototype.isStatement = YES; - - Try.prototype.jumps = function(o) { - var _ref2; - return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0); - }; - - Try.prototype.makeReturn = function(res) { - if (this.attempt) this.attempt = this.attempt.makeReturn(res); - if (this.recovery) this.recovery = this.recovery.makeReturn(res); - return this; - }; - - Try.prototype.compileNode = function(o) { - var catchPart, ensurePart, errorPart, tryPart; - o.indent += TAB; - errorPart = this.error ? " (" + (this.error.compile(o)) + ") " : ' '; - tryPart = this.attempt.compile(o, LEVEL_TOP); - catchPart = this.recovery ? (!o.scope.check(this.error.value) ? o.scope.add(this.error.value, 'param') : void 0, " catch" + errorPart + "{\n" + (this.recovery.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}") : !(this.ensure || this.recovery) ? ' catch (_error) {}' : void 0; - ensurePart = this.ensure ? " finally {\n" + (this.ensure.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" : ''; - return "" + this.tab + "try {\n" + tryPart + "\n" + this.tab + "}" + (catchPart || '') + ensurePart; - }; - - return Try; - - })(Base); - - exports.Throw = Throw = (function(_super) { - - __extends(Throw, _super); - - function Throw(expression) { - this.expression = expression; - } - - Throw.prototype.children = ['expression']; - - Throw.prototype.isStatement = YES; - - Throw.prototype.jumps = NO; - - Throw.prototype.makeReturn = THIS; - - Throw.prototype.compileNode = function(o) { - return this.tab + ("throw " + (this.expression.compile(o)) + ";"); - }; - - return Throw; - - })(Base); - - exports.Existence = Existence = (function(_super) { - - __extends(Existence, _super); - - function Existence(expression) { - this.expression = expression; - } - - Existence.prototype.children = ['expression']; - - Existence.prototype.invert = NEGATE; - - Existence.prototype.compileNode = function(o) { - var cmp, cnj, code, _ref2; - this.expression.front = this.front; - code = this.expression.compile(o, LEVEL_OP); - if (IDENTIFIER.test(code) && !o.scope.check(code)) { - _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1]; - code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null"; - } else { - code = "" + code + " " + (this.negated ? '==' : '!=') + " null"; - } - if (o.level <= LEVEL_COND) { - return code; - } else { - return "(" + code + ")"; - } - }; - - return Existence; - - })(Base); - - exports.Parens = Parens = (function(_super) { - - __extends(Parens, _super); - - function Parens(body) { - this.body = body; - } - - Parens.prototype.children = ['body']; - - Parens.prototype.unwrap = function() { - return this.body; - }; - - Parens.prototype.isComplex = function() { - return this.body.isComplex(); - }; - - Parens.prototype.compileNode = function(o) { - var bare, code, expr; - expr = this.body.unwrap(); - if (expr instanceof Value && expr.isAtomic()) { - expr.front = this.front; - return expr.compile(o); - } - code = expr.compile(o, LEVEL_PAREN); - bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns)); - if (bare) { - return code; - } else { - return "(" + code + ")"; - } - }; - - return Parens; - - })(Base); - - exports.For = For = (function(_super) { - - __extends(For, _super); - - function For(body, source) { - var _ref2; - this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index; - this.body = Block.wrap([body]); - this.own = !!source.own; - this.object = !!source.object; - if (this.object) { - _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; - } - if (this.index instanceof Value) { - throw SyntaxError('index cannot be a pattern matching expression'); - } - this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; - this.pattern = this.name instanceof Value; - if (this.range && this.index) { - throw SyntaxError('indexes do not apply to range loops'); - } - if (this.range && this.pattern) { - throw SyntaxError('cannot pattern match over range loops'); - } - this.returns = false; - } - - For.prototype.children = ['body', 'source', 'guard', 'step']; - - For.prototype.compileNode = function(o) { - var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2; - body = Block.wrap([this.body]); - lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0; - if (lastJumps && lastJumps instanceof Return) this.returns = false; - source = this.range ? this.source.base : this.source; - scope = o.scope; - name = this.name && this.name.compile(o, LEVEL_LIST); - index = this.index && this.index.compile(o, LEVEL_LIST); - if (name && !this.pattern) { - scope.find(name, { - immediate: true - }); - } - if (index) { - scope.find(index, { - immediate: true - }); - } - if (this.returns) rvar = scope.freeVariable('results'); - ivar = (this.range ? name : index) || scope.freeVariable('i'); - if (this.step && !this.range) stepvar = scope.freeVariable("step"); - if (this.pattern) name = ivar; - varPart = ''; - guardPart = ''; - defPart = ''; - idt1 = this.tab + TAB; - if (this.range) { - forPart = source.compile(merge(o, { - index: ivar, - step: this.step - })); - } else { - svar = this.source.compile(o, LEVEL_LIST); - if ((name || this.own) && !IDENTIFIER.test(svar)) { - defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; - svar = ref; - } - if (name && !this.pattern) { - namePart = "" + name + " = " + svar + "[" + ivar + "]"; - } - if (!this.object) { - lvar = scope.freeVariable('len'); - forVarPart = ("" + ivar + " = 0, " + lvar + " = " + svar + ".length") + (this.step ? ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP)) : ''); - stepPart = this.step ? "" + ivar + " += " + stepvar : "" + ivar + "++"; - forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart; - } - } - if (this.returns) { - resultPart = "" + this.tab + rvar + " = [];\n"; - returnResult = "\n" + this.tab + "return " + rvar + ";"; - body.makeReturn(rvar); - } - if (this.guard) { - if (body.expressions.length > 1) { - body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); - } else { - if (this.guard) body = Block.wrap([new If(this.guard, body)]); - } - } - if (this.pattern) { - body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + ivar + "]"))); - } - defPart += this.pluckDirectCall(o, body); - if (namePart) varPart = "\n" + idt1 + namePart + ";"; - if (this.object) { - forPart = "" + ivar + " in " + svar; - if (this.own) { - guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")) continue;"; - } - } - body = body.compile(merge(o, { - indent: idt1 - }), LEVEL_TOP); - if (body) body = '\n' + body + '\n'; - return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + varPart + body + this.tab + "}" + (returnResult || ''); - }; - - For.prototype.pluckDirectCall = function(o, body) { - var base, defs, expr, fn, idx, ref, val, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; - defs = ''; - _ref2 = body.expressions; - for (idx = 0, _len = _ref2.length; idx < _len; idx++) { - expr = _ref2[idx]; - expr = expr.unwrapAll(); - if (!(expr instanceof Call)) continue; - val = expr.variable.unwrapAll(); - if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) { - continue; - } - fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val; - ref = new Literal(o.scope.freeVariable('fn')); - base = new Value(ref); - if (val.base) _ref7 = [base, val], val.base = _ref7[0], base = _ref7[1]; - body.expressions[idx] = new Call(base, expr.args); - defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'; - } - return defs; - }; - - return For; - - })(While); - - exports.Switch = Switch = (function(_super) { - - __extends(Switch, _super); - - function Switch(subject, cases, otherwise) { - this.subject = subject; - this.cases = cases; - this.otherwise = otherwise; - } - - Switch.prototype.children = ['subject', 'cases', 'otherwise']; - - Switch.prototype.isStatement = YES; - - Switch.prototype.jumps = function(o) { - var block, conds, _i, _len, _ref2, _ref3, _ref4; - if (o == null) { - o = { - block: true - }; - } - _ref2 = this.cases; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1]; - if (block.jumps(o)) return block; - } - return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0; - }; - - Switch.prototype.makeReturn = function(res) { - var pair, _i, _len, _ref2, _ref3; - _ref2 = this.cases; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - pair = _ref2[_i]; - pair[1].makeReturn(res); - } - if (res) { - this.otherwise || (this.otherwise = new Block([new Literal('void 0')])); - } - if ((_ref3 = this.otherwise) != null) _ref3.makeReturn(res); - return this; - }; - - Switch.prototype.compileNode = function(o) { - var block, body, code, cond, conditions, expr, i, idt1, idt2, _i, _len, _len2, _ref2, _ref3, _ref4, _ref5; - idt1 = o.indent + TAB; - idt2 = o.indent = idt1 + TAB; - code = this.tab + ("switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o, LEVEL_PAREN) : void 0) || false) + ") {\n"); - _ref3 = this.cases; - for (i = 0, _len = _ref3.length; i < _len; i++) { - _ref4 = _ref3[i], conditions = _ref4[0], block = _ref4[1]; - _ref5 = flatten([conditions]); - for (_i = 0, _len2 = _ref5.length; _i < _len2; _i++) { - cond = _ref5[_i]; - if (!this.subject) cond = cond.invert(); - code += idt1 + ("case " + (cond.compile(o, LEVEL_PAREN)) + ":\n"); - } - if (body = block.compile(o, LEVEL_TOP)) code += body + '\n'; - if (i === this.cases.length - 1 && !this.otherwise) break; - expr = this.lastNonComment(block.expressions); - if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) { - continue; - } - code += idt2 + 'break;\n'; - } - if (this.otherwise && this.otherwise.expressions.length) { - code += idt1 + ("default:\n" + (this.otherwise.compile(o, LEVEL_TOP)) + "\n"); - } - return code + this.tab + '}'; - }; - - return Switch; - - })(Base); - - exports.If = If = (function(_super) { - - __extends(If, _super); - - function If(condition, body, options) { - this.body = body; - if (options == null) options = {}; - this.condition = options.type === 'unless' ? condition.invert() : condition; - this.elseBody = null; - this.isChain = false; - this.soak = options.soak; - } - - If.prototype.children = ['condition', 'body', 'elseBody']; - - If.prototype.bodyNode = function() { - var _ref2; - return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0; - }; - - If.prototype.elseBodyNode = function() { - var _ref2; - return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0; - }; - - If.prototype.addElse = function(elseBody) { - if (this.isChain) { - this.elseBodyNode().addElse(elseBody); - } else { - this.isChain = elseBody instanceof If; - this.elseBody = this.ensureBlock(elseBody); - } - return this; - }; - - If.prototype.isStatement = function(o) { - var _ref2; - return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0); - }; - - If.prototype.jumps = function(o) { - var _ref2; - return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0); - }; - - If.prototype.compileNode = function(o) { - if (this.isStatement(o)) { - return this.compileStatement(o); - } else { - return this.compileExpression(o); - } - }; - - If.prototype.makeReturn = function(res) { - if (res) { - this.elseBody || (this.elseBody = new Block([new Literal('void 0')])); - } - this.body && (this.body = new Block([this.body.makeReturn(res)])); - this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)])); - return this; - }; - - If.prototype.ensureBlock = function(node) { - if (node instanceof Block) { - return node; - } else { - return new Block([node]); - } - }; - - If.prototype.compileStatement = function(o) { - var body, bodyc, child, cond, exeq, ifPart, _ref2; - child = del(o, 'chainChild'); - exeq = del(o, 'isExistentialEquals'); - if (exeq) { - return new If(this.condition.invert(), this.elseBodyNode(), { - type: 'if' - }).compile(o); - } - cond = this.condition.compile(o, LEVEL_PAREN); - o.indent += TAB; - body = this.ensureBlock(this.body); - bodyc = body.compile(o); - if (1 === ((_ref2 = body.expressions) != null ? _ref2.length : void 0) && !this.elseBody && !child && bodyc && cond && -1 === (bodyc.indexOf('\n')) && 80 > cond.length + bodyc.length) { - return "" + this.tab + "if (" + cond + ") " + (bodyc.replace(/^\s+/, '')); - } - if (bodyc) bodyc = "\n" + bodyc + "\n" + this.tab; - ifPart = "if (" + cond + ") {" + bodyc + "}"; - if (!child) ifPart = this.tab + ifPart; - if (!this.elseBody) return ifPart; - return ifPart + ' else ' + (this.isChain ? (o.indent = this.tab, o.chainChild = true, this.elseBody.unwrap().compile(o, LEVEL_TOP)) : "{\n" + (this.elseBody.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}"); - }; - - If.prototype.compileExpression = function(o) { - var alt, body, code, cond; - cond = this.condition.compile(o, LEVEL_COND); - body = this.bodyNode().compile(o, LEVEL_LIST); - alt = this.elseBodyNode() ? this.elseBodyNode().compile(o, LEVEL_LIST) : 'void 0'; - code = "" + cond + " ? " + body + " : " + alt; - if (o.level >= LEVEL_COND) { - return "(" + code + ")"; - } else { - return code; - } - }; - - If.prototype.unfoldSoak = function() { - return this.soak && this; - }; - - return If; - - })(Base); - - Closure = { - wrap: function(expressions, statement, noReturn) { - var args, call, func, mentionsArgs, meth; - if (expressions.jumps()) return expressions; - func = new Code([], Block.wrap([expressions])); - args = []; - if ((mentionsArgs = expressions.contains(this.literalArgs)) || expressions.contains(this.literalThis)) { - meth = new Literal(mentionsArgs ? 'apply' : 'call'); - args = [new Literal('this')]; - if (mentionsArgs) args.push(new Literal('arguments')); - func = new Value(func, [new Access(meth)]); - } - func.noReturn = noReturn; - call = new Call(func, args); - if (statement) { - return Block.wrap([call]); - } else { - return call; - } - }, - literalArgs: function(node) { - return node instanceof Literal && node.value === 'arguments' && !node.asKey; - }, - literalThis: function(node) { - return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound); - } - }; - - unfoldSoak = function(o, parent, name) { - var ifn; - if (!(ifn = parent[name].unfoldSoak(o))) return; - parent[name] = ifn.body; - ifn.body = new Value(parent); - return ifn; - }; - - UTILITIES = { - "extends": function() { - return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }"; - }, - bind: function() { - return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }'; - }, - indexOf: function() { - return "Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }"; - }, - hasProp: function() { - return 'Object.prototype.hasOwnProperty'; - }, - slice: function() { - return 'Array.prototype.slice'; - } - }; - - LEVEL_TOP = 1; - - LEVEL_PAREN = 2; - - LEVEL_LIST = 3; - - LEVEL_COND = 4; - - LEVEL_OP = 5; - - LEVEL_ACCESS = 6; - - TAB = ' '; - - IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*"; - - IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$"); - - SIMPLENUM = /^[+-]?\d+$/; - - METHOD_DEF = RegExp("^(?:(" + IDENTIFIER_STR + ")\\.prototype(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\]))|(" + IDENTIFIER_STR + ")$"); - - IS_STRING = /^['"]/; - - utility = function(name) { - var ref; - ref = "__" + name; - Scope.root.assign(ref, UTILITIES[name]()); - return ref; - }; - - multident = function(code, tab) { - code = code.replace(/\n/g, '$&' + tab); - return code.replace(/\s+$/, ''); - }; - -}).call(this); - -};require['./coffee-script'] = new function() { - var exports = this; - (function() { - var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref, - __hasProp = Object.prototype.hasOwnProperty; - - fs = require('fs'); - - path = require('path'); - - _ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED; - - parser = require('./parser').parser; - - vm = require('vm'); - - if (require.extensions) { - require.extensions['.coffee'] = function(module, filename) { - var content; - content = compile(fs.readFileSync(filename, 'utf8'), { - filename: filename - }); - return module._compile(content, filename); - }; - } else if (require.registerExtension) { - require.registerExtension('.coffee', function(content) { - return compile(content); - }); - } - - exports.VERSION = '1.2.0'; - - exports.RESERVED = RESERVED; - - exports.helpers = require('./helpers'); - - exports.compile = compile = function(code, options) { - var merge; - if (options == null) options = {}; - merge = exports.helpers.merge; - try { - return (parser.parse(lexer.tokenize(code))).compile(merge({}, options)); - } catch (err) { - if (options.filename) { - err.message = "In " + options.filename + ", " + err.message; - } - throw err; - } - }; - - exports.tokens = function(code, options) { - return lexer.tokenize(code, options); - }; - - exports.nodes = function(source, options) { - if (typeof source === 'string') { - return parser.parse(lexer.tokenize(source, options)); - } else { - return parser.parse(source); - } - }; - - exports.run = function(code, options) { - var mainModule; - mainModule = require.main; - mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.'; - mainModule.moduleCache && (mainModule.moduleCache = {}); - mainModule.paths = require('module')._nodeModulePaths(path.dirname(options.filename)); - if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) { - return mainModule._compile(compile(code, options), mainModule.filename); - } else { - return mainModule._compile(code, mainModule.filename); - } - }; - - exports.eval = function(code, options) { - var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref2, _ref3, _require; - if (options == null) options = {}; - if (!(code = code.trim())) return; - Script = vm.Script; - if (Script) { - if (options.sandbox != null) { - if (options.sandbox instanceof Script.createContext().constructor) { - sandbox = options.sandbox; - } else { - sandbox = Script.createContext(); - _ref2 = options.sandbox; - for (k in _ref2) { - if (!__hasProp.call(_ref2, k)) continue; - v = _ref2[k]; - sandbox[k] = v; - } - } - sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox; - } else { - sandbox = global; - } - sandbox.__filename = options.filename || 'eval'; - sandbox.__dirname = path.dirname(sandbox.__filename); - if (!(sandbox !== global || sandbox.module || sandbox.require)) { - Module = require('module'); - sandbox.module = _module = new Module(options.modulename || 'eval'); - sandbox.require = _require = function(path) { - return Module._load(path, _module, true); - }; - _module.filename = sandbox.__filename; - _ref3 = Object.getOwnPropertyNames(require); - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - r = _ref3[_i]; - if (r !== 'paths') _require[r] = require[r]; - } - _require.paths = _module.paths = Module._nodeModulePaths(process.cwd()); - _require.resolve = function(request) { - return Module._resolveFilename(request, _module); - }; - } - } - o = {}; - for (k in options) { - if (!__hasProp.call(options, k)) continue; - v = options[k]; - o[k] = v; - } - o.bare = true; - js = compile(code, o); - if (sandbox === global) { - return vm.runInThisContext(js); - } else { - return vm.runInContext(js, sandbox); - } - }; - - lexer = new Lexer; - - parser.lexer = { - lex: function() { - var tag, _ref2; - _ref2 = this.tokens[this.pos++] || [''], tag = _ref2[0], this.yytext = _ref2[1], this.yylineno = _ref2[2]; - return tag; - }, - setInput: function(tokens) { - this.tokens = tokens; - return this.pos = 0; - }, - upcomingInput: function() { - return ""; - } - }; - - parser.yy = require('./nodes'); - -}).call(this); - -};require['./browser'] = new function() { - var exports = this; - (function() { - var CoffeeScript, runScripts; - - CoffeeScript = require('./coffee-script'); - - CoffeeScript.require = require; - - CoffeeScript.eval = function(code, options) { - return eval(CoffeeScript.compile(code, options)); - }; - - CoffeeScript.run = function(code, options) { - if (options == null) options = {}; - options.bare = true; - return Function(CoffeeScript.compile(code, options))(); - }; - - if (typeof window === "undefined" || window === null) return; - - CoffeeScript.load = function(url, callback) { - var xhr; - xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP'); - xhr.open('GET', url, true); - if ('overrideMimeType' in xhr) xhr.overrideMimeType('text/plain'); - xhr.onreadystatechange = function() { - var _ref; - if (xhr.readyState === 4) { - if ((_ref = xhr.status) === 0 || _ref === 200) { - CoffeeScript.run(xhr.responseText); - } else { - throw new Error("Could not load " + url); - } - if (callback) return callback(); - } - }; - return xhr.send(null); - }; - - runScripts = function() { - var coffees, execute, index, length, s, scripts; - scripts = document.getElementsByTagName('script'); - coffees = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = scripts.length; _i < _len; _i++) { - s = scripts[_i]; - if (s.type === 'text/coffeescript') _results.push(s); - } - return _results; - })(); - index = 0; - length = coffees.length; - (execute = function() { - var script; - script = coffees[index++]; - if ((script != null ? script.type : void 0) === 'text/coffeescript') { - if (script.src) { - return CoffeeScript.load(script.src, execute); - } else { - CoffeeScript.run(script.innerHTML); - return execute(); - } - } - })(); - return null; - }; - - if (window.addEventListener) { - addEventListener('DOMContentLoaded', runScripts, false); - } else { - attachEvent('onload', runScripts); - } - -}).call(this); - -}; - return require['./coffee-script']; - }(); - - if (typeof define === 'function' && define.amd) { - // define[NOTE: Added so it doesn't match regex /define\(/](function() { return CoffeeScript; }); - } else { - root.CoffeeScript = CoffeeScript; - } -}(this)); diff --git a/vendor/d3.v3.js b/vendor/d3.v3.js deleted file mode 100644 index 308385f6a..000000000 --- a/vendor/d3.v3.js +++ /dev/null @@ -1,7812 +0,0 @@ -// Modified to include a module.exports of the d3 variable -(function() { - var d3_format_decimalPoint = ".", d3_format_thousandsSeparator = ",", d3_format_grouping = [ 3, 3 ]; - if (!Date.now) Date.now = function() { - return +new Date(); - }; - try { - document.createElement("div").style.setProperty("opacity", 0, ""); - } catch (error) { - var d3_style_prototype = CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); - }; - } - var d3 = { - version: "3.0.0" - }; - var π = Math.PI, ε = 1e-6, d3_radians = π / 180, d3_degrees = 180 / π; - function d3_target(d) { - return d.target; - } - function d3_source(d) { - return d.source; - } - function d3_class(ctor, properties) { - try { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } catch (e) { - ctor.prototype = properties; - } - } - var d3_array = d3_arraySlice; - function d3_arrayCopy(pseudoarray) { - var i = -1, n = pseudoarray.length, array = []; - while (++i < n) array.push(pseudoarray[i]); - return array; - } - function d3_arraySlice(pseudoarray) { - return Array.prototype.slice.call(pseudoarray); - } - try { - d3_array(document.documentElement.childNodes)[0].nodeType; - } catch (e) { - d3_array = d3_arrayCopy; - } - var d3_arraySubclass = [].__proto__ ? function(array, prototype) { - array.__proto__ = prototype; - } : function(array, prototype) { - for (var property in prototype) array[property] = prototype[property]; - }; - d3.map = function(object) { - var map = new d3_Map(); - for (var key in object) map.set(key, object[key]); - return map; - }; - function d3_Map() {} - d3_class(d3_Map, { - has: function(key) { - return d3_map_prefix + key in this; - }, - get: function(key) { - return this[d3_map_prefix + key]; - }, - set: function(key, value) { - return this[d3_map_prefix + key] = value; - }, - remove: function(key) { - key = d3_map_prefix + key; - return key in this && delete this[key]; - }, - keys: function() { - var keys = []; - this.forEach(function(key) { - keys.push(key); - }); - return keys; - }, - values: function() { - var values = []; - this.forEach(function(key, value) { - values.push(value); - }); - return values; - }, - entries: function() { - var entries = []; - this.forEach(function(key, value) { - entries.push({ - key: key, - value: value - }); - }); - return entries; - }, - forEach: function(f) { - for (var key in this) { - if (key.charCodeAt(0) === d3_map_prefixCode) { - f.call(this, key.substring(1), this[key]); - } - } - } - }); - var d3_map_prefix = "\0", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); - function d3_identity(d) { - return d; - } - function d3_true() { - return true; - } - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return arguments.length ? target : value; - }; - } - d3.ascending = function(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - }; - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.mean = function(array, f) { - var n = array.length, a, m = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; - } else { - while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; - } - return j ? m : undefined; - }; - d3.median = function(array, f) { - if (arguments.length > 1) array = array.map(f); - array = array.filter(d3_number); - return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined; - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [ a, c ]; - }; - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - var random = d3.random.normal(); - return function() { - return Math.exp(µ + σ * random()); - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s / m; - }; - } - }; - function d3_number(x) { - return x != null && !isNaN(x); - } - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (!isNaN(a = +array[i])) s += a; - } else { - while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.shuffle = function(array) { - var m = array.length, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m], array[m] = array[i], array[i] = t; - } - return array; - }; - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; - } - } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.bisector = function(f) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - }; - var d3_bisector = d3.bisector(function(d) { - return d; - }); - d3.bisectLeft = d3_bisector.left; - d3.bisect = d3.bisectRight = d3_bisector.right; - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, valuesByKey = new d3_Map(), values, o = {}; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - valuesByKey.forEach(function(keyValue, values) { - o[keyValue] = map(values, depth); - }); - return o; - } - function entries(map, depth) { - if (depth >= keys.length) return map; - var a = [], sortKey = sortKeys[depth++], key; - for (key in map) { - a.push({ - key: key, - values: entries(map[key], depth) - }); - } - if (sortKey) a.sort(function(a, b) { - return sortKey(a.key, b.key); - }); - return a; - } - nest.map = function(array) { - return map(array, 0); - }; - nest.entries = function(array) { - return entries(map(array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.permute = function(array, indexes) { - var permutes = [], i = -1, n = indexes.length; - while (++i < n) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.merge = function(arrays) { - return Array.prototype.concat.apply([], arrays); - }; - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(Math.abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - d3.xhr = function(url, mimeType, callback) { - var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var s = request.status; - !s && request.responseText || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request); - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - }; - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - d3.text = function() { - return d3.xhr.apply(d3, arguments).response(d3_text); - }; - function d3_text(request) { - return request.responseText; - } - d3.json = function(url, callback) { - return d3.xhr(url, "application/json", callback).response(d3_json); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - return d3.xhr(url, "text/html", callback).response(d3_html); - }; - function d3_html(request) { - var range = document.createRange(); - range.selectNode(document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = function() { - return d3.xhr.apply(d3, arguments).response(d3_xml); - }; - function d3_xml(request) { - return request.responseXML; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0) { - prefix = name.substring(0, i); - name = name.substring(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i > 0) { - name = type.substring(i + 1); - type = type.substring(0, i); - } - return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.format = function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", basePrefix = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, suffix = "", integer = false; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - if (comma) width -= Math.floor((width - 1) / 4); - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (basePrefix) basePrefix = "0" + type.toLowerCase(); - - case "c": - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (basePrefix === "#") basePrefix = ""; - if (type == "r" && !precision) type = "g"; - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; - if (scale < 0) { - var prefix = d3.formatPrefix(value, precision); - value = prefix.scale(value); - suffix = prefix.symbol; - } else { - value *= scale; - } - value = type(value, precision); - if (!zfill && comma) value = d3_format_group(value); - var length = basePrefix.length + value.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) value = d3_format_group(padding + value); - if (d3_format_decimalPoint) value.replace(".", d3_format_decimalPoint); - negative += basePrefix; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + suffix; - }; - }; - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return d3.round(x, p = d3_format_precision(x, p)).toFixed(Math.max(0, Math.min(20, p))); - } - }); - function d3_format_precision(x, p) { - return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1); - } - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_format_group = d3_identity; - if (d3_format_grouping) { - var d3_format_groupingLength = d3_format_grouping.length; - d3_format_group = function(value) { - var i = value.lastIndexOf("."), f = i >= 0 ? "." + value.substring(i + 1) : (i = value.length, - ""), t = [], j = 0, g = d3_format_grouping[0]; - while (i > 0 && g > 0) { - t.push(value.substring(i -= g, i + g)); - g = d3_format_grouping[j = (j + 1) % d3_format_groupingLength]; - } - return t.reverse().join(d3_format_thousandsSeparator || "") + f; - }; - } - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "μ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, Math.abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, Array.prototype.slice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * π / 2); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / (2 * π) * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * π / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.event = null; - function d3_eventCancel() { - d3.event.stopPropagation(); - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - return dispatch; - } - d3.transform = function(string) { - var g = document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolate = function(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - }; - d3.interpolateNumber = function(a, b) { - b -= a; - return function(t) { - return a + b * t; - }; - }; - d3.interpolateRound = function(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - }; - d3.interpolateString = function(a, b) { - var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; - d3_interpolate_number.lastIndex = 0; - for (i = 0; m = d3_interpolate_number.exec(b); ++i) { - if (m.index) s.push(b.substring(s0, s1 = m.index)); - q.push({ - i: s.length, - x: m[0] - }); - s.push(null); - s0 = d3_interpolate_number.lastIndex; - } - if (s0 < b.length) s.push(b.substring(s0)); - for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { - o = q[i]; - if (o.x == m[0]) { - if (o.i) { - if (s[o.i + 1] == null) { - s[o.i - 1] += o.x; - s.splice(o.i, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } else { - s[o.i - 1] += o.x + s[o.i + 1]; - s.splice(o.i, 2); - for (j = i + 1; j < n; ++j) q[j].i -= 2; - } - } else { - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } - } - q.splice(i, 1); - n--; - i--; - } else { - o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); - } - } - while (i < n) { - o = q.pop(); - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - } - n--; - } - if (s.length === 1) { - return s[0] == null ? q[0].x : function() { - return b; - }; - } - return function(t) { - for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - }; - d3.interpolateTransform = function(a, b) { - var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({ - i: 1, - x: d3.interpolateNumber(ta[0], tb[0]) - }, { - i: 3, - x: d3.interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(s.pop() + "rotate(", null, ")") - 2, - x: d3.interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - if (wa != wb) { - q.push({ - i: s.push(s.pop() + "skewX(", null, ")") - 2, - x: d3.interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({ - i: n - 4, - x: d3.interpolateNumber(ka[0], kb[0]) - }, { - i: n - 2, - x: d3.interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - }; - d3.interpolateRgb = function(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - }; - d3.interpolateHsl = function(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var h0 = a.h, s0 = a.s, l0 = a.l, h1 = b.h - h0, s1 = b.s - s0, l1 = b.l - l0; - if (h1 > 180) h1 -= 360; else if (h1 < -180) h1 += 360; - return function(t) { - return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t) + ""; - }; - }; - d3.interpolateLab = function(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - }; - d3.interpolateHcl = function(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - }; - d3.interpolateArray = function(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - }; - d3.interpolateObject = function(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolateByName(k)(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - }; - var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; - function d3_interpolateByName(name) { - return name == "transform" ? d3.interpolateTransform : d3.interpolate; - } - d3.interpolators = [ d3.interpolateObject, function(a, b) { - return b instanceof Array && d3.interpolateArray(a, b); - }, function(a, b) { - return (typeof a === "string" || typeof b === "string") && d3.interpolateString(a + "", b + ""); - }, function(a, b) { - return (typeof b === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Color) && d3.interpolateRgb(a, b); - }, function(a, b) { - return !isNaN(a = +a) && !isNaN(b = +b) && d3.interpolateNumber(a, b); - } ]; - function d3_uninterpolateNumber(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return (x - a) * b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return Math.max(0, Math.min(1, (x - a) * b)); - }; - } - function d3_Color() {} - d3_Color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.rgb = function(r, g, b) { - return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); - }; - function d3_rgb(r, g, b) { - return new d3_Rgb(r, g, b); - } - function d3_Rgb(r, g, b) { - this.r = r; - this.g = g; - this.b = b; - } - var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return d3_rgb(Math.min(255, Math.floor(r / k)), Math.min(255, Math.floor(g / k)), Math.min(255, Math.floor(b / k))); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_rgb(Math.floor(k * this.r), Math.floor(k * this.g), Math.floor(k * this.b)); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - var r = 0, g = 0, b = 0, m1, m2, name; - m1 = /([a-z]+)\((.*)\)/i.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); - if (format != null && format.charAt(0) === "#") { - if (format.length === 4) { - r = format.charAt(1); - r += r; - g = format.charAt(2); - g += g; - b = format.charAt(3); - b += b; - } else if (format.length === 7) { - r = format.substring(1, 3); - g = format.substring(3, 5); - b = format.substring(5, 7); - } - r = parseInt(r, 16); - g = parseInt(g, 16); - b = parseInt(b, 16); - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - s = h = 0; - } - return d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: "#f0f8ff", - antiquewhite: "#faebd7", - aqua: "#00ffff", - aquamarine: "#7fffd4", - azure: "#f0ffff", - beige: "#f5f5dc", - bisque: "#ffe4c4", - black: "#000000", - blanchedalmond: "#ffebcd", - blue: "#0000ff", - blueviolet: "#8a2be2", - brown: "#a52a2a", - burlywood: "#deb887", - cadetblue: "#5f9ea0", - chartreuse: "#7fff00", - chocolate: "#d2691e", - coral: "#ff7f50", - cornflowerblue: "#6495ed", - cornsilk: "#fff8dc", - crimson: "#dc143c", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgoldenrod: "#b8860b", - darkgray: "#a9a9a9", - darkgreen: "#006400", - darkgrey: "#a9a9a9", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkseagreen: "#8fbc8f", - darkslateblue: "#483d8b", - darkslategray: "#2f4f4f", - darkslategrey: "#2f4f4f", - darkturquoise: "#00ced1", - darkviolet: "#9400d3", - deeppink: "#ff1493", - deepskyblue: "#00bfff", - dimgray: "#696969", - dimgrey: "#696969", - dodgerblue: "#1e90ff", - firebrick: "#b22222", - floralwhite: "#fffaf0", - forestgreen: "#228b22", - fuchsia: "#ff00ff", - gainsboro: "#dcdcdc", - ghostwhite: "#f8f8ff", - gold: "#ffd700", - goldenrod: "#daa520", - gray: "#808080", - green: "#008000", - greenyellow: "#adff2f", - grey: "#808080", - honeydew: "#f0fff0", - hotpink: "#ff69b4", - indianred: "#cd5c5c", - indigo: "#4b0082", - ivory: "#fffff0", - khaki: "#f0e68c", - lavender: "#e6e6fa", - lavenderblush: "#fff0f5", - lawngreen: "#7cfc00", - lemonchiffon: "#fffacd", - lightblue: "#add8e6", - lightcoral: "#f08080", - lightcyan: "#e0ffff", - lightgoldenrodyellow: "#fafad2", - lightgray: "#d3d3d3", - lightgreen: "#90ee90", - lightgrey: "#d3d3d3", - lightpink: "#ffb6c1", - lightsalmon: "#ffa07a", - lightseagreen: "#20b2aa", - lightskyblue: "#87cefa", - lightslategray: "#778899", - lightslategrey: "#778899", - lightsteelblue: "#b0c4de", - lightyellow: "#ffffe0", - lime: "#00ff00", - limegreen: "#32cd32", - linen: "#faf0e6", - magenta: "#ff00ff", - maroon: "#800000", - mediumaquamarine: "#66cdaa", - mediumblue: "#0000cd", - mediumorchid: "#ba55d3", - mediumpurple: "#9370db", - mediumseagreen: "#3cb371", - mediumslateblue: "#7b68ee", - mediumspringgreen: "#00fa9a", - mediumturquoise: "#48d1cc", - mediumvioletred: "#c71585", - midnightblue: "#191970", - mintcream: "#f5fffa", - mistyrose: "#ffe4e1", - moccasin: "#ffe4b5", - navajowhite: "#ffdead", - navy: "#000080", - oldlace: "#fdf5e6", - olive: "#808000", - olivedrab: "#6b8e23", - orange: "#ffa500", - orangered: "#ff4500", - orchid: "#da70d6", - palegoldenrod: "#eee8aa", - palegreen: "#98fb98", - paleturquoise: "#afeeee", - palevioletred: "#db7093", - papayawhip: "#ffefd5", - peachpuff: "#ffdab9", - peru: "#cd853f", - pink: "#ffc0cb", - plum: "#dda0dd", - powderblue: "#b0e0e6", - purple: "#800080", - red: "#ff0000", - rosybrown: "#bc8f8f", - royalblue: "#4169e1", - saddlebrown: "#8b4513", - salmon: "#fa8072", - sandybrown: "#f4a460", - seagreen: "#2e8b57", - seashell: "#fff5ee", - sienna: "#a0522d", - silver: "#c0c0c0", - skyblue: "#87ceeb", - slateblue: "#6a5acd", - slategray: "#708090", - slategrey: "#708090", - snow: "#fffafa", - springgreen: "#00ff7f", - steelblue: "#4682b4", - tan: "#d2b48c", - teal: "#008080", - thistle: "#d8bfd8", - tomato: "#ff6347", - turquoise: "#40e0d0", - violet: "#ee82ee", - wheat: "#f5deb3", - white: "#ffffff", - whitesmoke: "#f5f5f5", - yellow: "#ffff00", - yellowgreen: "#9acd32" - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgb_parse(value, d3_rgb, d3_hsl_rgb)); - }); - d3.hsl = function(h, s, l) { - return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); - }; - function d3_hsl(h, s, l) { - return new d3_Hsl(h, s, l); - } - function d3_Hsl(h, s, l) { - this.h = h; - this.s = s; - this.l = l; - } - var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = h % 360; - if (h < 0) h += 360; - s = s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = function(h, c, l) { - return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); - }; - function d3_hcl(h, c, l) { - return new d3_Hcl(h, c, l); - } - function d3_Hcl(h, c, l) { - this.h = h; - this.c = c; - this.l = l; - } - var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); - d3_hclPrototype.brighter = function(k) { - return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = function(l, a, b) { - return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); - }; - function d3_lab(l, a, b) { - return new d3_Lab(l, a, b); - } - function d3_Lab(l, a, b) { - this.l = l; - this.a = a; - this.b = b; - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_Lab.prototype = new d3_Color(); - d3_labPrototype.brighter = function(k) { - return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return d3_hcl(Math.atan2(b, a) / π * 180, Math.sqrt(a * a + b * b), l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - function d3_selection(groups) { - d3_arraySubclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectRoot = document.documentElement, d3_selectMatcher = d3_selectRoot.matchesSelector || d3_selectRoot.webkitMatchesSelector || d3_selectRoot.mozMatchesSelector || d3_selectRoot.msMatchesSelector || d3_selectRoot.oMatchesSelector, d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = function(s, n) { - return Sizzle.uniqueSort(Sizzle(s, n)); - }; - d3_selectMatches = Sizzle.matchesSelector; - } - var d3_selectionPrototype = []; - d3.selection = function() { - return d3_selectionRoot; - }; - d3.selection.prototype = d3_selectionPrototype; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - if (typeof selector !== "function") selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - if (typeof selector !== "function") selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return function() { - return d3_selectAll(selector, this); - }; - } - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = name.trim().split(/^|\s+/g)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.className; - if (value.baseVal != null) value = value.baseVal; - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classed(name, value) { - name = name.trim().split(/\s+/).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.className, cb = c.baseVal != null, cv = cb ? c.baseVal : c; - if (value) { - re.lastIndex = 0; - if (!re.test(cv)) { - cv = d3_collapse(cv + " " + name); - if (cb) c.baseVal = cv; else node.className = cv; - } - } else if (cv) { - cv = d3_collapse(cv.replace(re, " ")); - if (cb) c.baseVal = cv; else node.className = cv; - } - }; - } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) return getComputedStyle(this.node(), null).getPropertyValue(name); - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); - } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3.ns.qualify(name); - function append() { - return this.appendChild(document.createElementNS(this.namespaceURI, name)); - } - function appendNS() { - return this.appendChild(document.createElementNS(name.space, name.local)); - } - return this.select(name.local ? appendNS : append); - }; - d3_selectionPrototype.insert = function(name, before) { - name = d3.ns.qualify(name); - function insert() { - return this.insertBefore(document.createElementNS(this.namespaceURI, name), d3_select(before, this)); - } - function insertNS() { - return this.insertBefore(document.createElementNS(name.space, name.local), d3_select(before, this)); - } - return this.select(name.local ? insertNS : insert); - }; - d3_selectionPrototype.remove = function() { - return this.each(function() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - }); - }; - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), n1 = Math.max(n, m), updateNodes = [], enterNodes = [], exitNodes = [], node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), keyValues = [], keyValue, j = groupData.length; - for (i = -1; ++i < n; ) { - keyValue = key.call(node = group[i], node.__data__, i); - if (nodeByKeyValue.has(keyValue)) { - exitNodes[j++] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues.push(keyValue); - } - for (i = -1; ++i < m; ) { - keyValue = key.call(groupData, nodeData = groupData[i], i); - if (nodeByKeyValue.has(keyValue)) { - updateNodes[i] = node = nodeByKeyValue.get(keyValue); - node.__data__ = nodeData; - enterNodes[i] = exitNodes[i] = null; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - updateNodes[i] = exitNodes[i] = null; - } - nodeByKeyValue.remove(keyValue); - } - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.has(keyValues[i])) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - enterNodes[i] = exitNodes[i] = null; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - updateNodes[i] = exitNodes[i] = null; - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - updateNodes[i] = exitNodes[i] = null; - } - for (;i < n1; ++i) { - exitNodes[i] = group[i]; - enterNodes[i] = updateNodes[i] = null; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3.ascending; - return function(a, b) { - return comparator(a && a.__data__, b && b.__data__); - }; - } - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."); - if (i > 0) type = type.substring(0, i); - function onRemove() { - var wrapper = this[name]; - if (wrapper) { - this.removeEventListener(type, wrapper, wrapper.$); - delete this[name]; - } - } - function onAdd() { - var node = this, args = d3_array(arguments); - onRemove.call(this); - this.addEventListener(type, this[name] = wrapper, wrapper.$ = capture); - wrapper._ = listener; - function wrapper(e) { - var o = d3.event; - d3.event = e; - args[0] = node.__data__; - try { - listener.apply(node, args); - } finally { - d3.event = o; - } - } - } - return listener ? onAdd : onRemove; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.transition = function() { - var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = Object.create(d3_transitionInherit); - transition.time = Date.now(); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, id, transition); - subgroup.push(node); - } - } - return d3_transition(subgroups, id); - }; - var d3_selectionRoot = d3_selection([ [ document ] ]); - d3_selectionRoot[0].parentNode = d3_selectRoot; - d3.select = function(selector) { - return typeof selector === "string" ? d3_selectionRoot.select(selector) : d3_selection([ [ selector ] ]); - }; - d3.selectAll = function(selector) { - return typeof selector === "string" ? d3_selectionRoot.selectAll(selector) : d3_selection([ d3_array(selector) ]); - }; - function d3_selection_enter(selection) { - d3_arraySubclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.insert = d3_selectionPrototype.insert; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_transition(groups, id) { - d3_arraySubclass(groups, d3_transitionPrototype); - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit = { - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3.transition = function(selection) { - return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); - }; - d3.transition.prototype = d3_transitionPrototype; - function d3_transitionNode(node, i, id, inherit) { - var lock = node.__transition__ || (node.__transition__ = { - active: 0, - count: 0 - }), transition = lock[id]; - if (!transition) { - var time = inherit.time; - transition = lock[id] = { - tween: new d3_Map(), - event: d3.dispatch("start", "end"), - time: time, - ease: inherit.ease, - delay: inherit.delay, - duration: inherit.duration - }; - ++lock.count; - d3.timer(function(elapsed) { - var d = node.__data__, ease = transition.ease, event = transition.event, delay = transition.delay, duration = transition.duration, tweened = []; - return delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time), 1; - function start(elapsed) { - if (lock.active > id) return stop(); - lock.active = id; - event.start.call(node, d, i); - transition.tween.forEach(function(key, value) { - if (value = value.call(node, d, i)) { - tweened.push(value); - } - }); - if (!tick(elapsed)) d3.timer(tick, 0, time); - return 1; - } - function tick(elapsed) { - if (lock.active !== id) return stop(); - var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length; - while (n > 0) { - tweened[--n].call(node, e); - } - if (t >= 1) { - stop(); - event.end.call(node, d, i); - return 1; - } - } - function stop() { - if (--lock.count) delete lock[id]; else delete node.__transition__; - return 1; - } - }, 0, time); - return transition; - } - } - d3_transitionPrototype.select = function(selector) { - var id = this.id, subgroups = [], subgroup, subnode, node; - if (typeof selector !== "function") selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, id, node.__transition__[id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; - if (typeof selector !== "function") selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node.__transition__[id]; - subnodes = selector.call(node, node.__data__, i); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - d3_transitionNode(subnode = subnodes[k], k, id, transition); - subgroup.push(subnode); - } - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i)) { - subgroup.push(node); - } - } - } - return d3_transition(subgroups, this.id, this.time).ease(this.ease()); - }; - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = d3_interpolateByName(nameNS), name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - return d3_transition_tween(this, "attr." + nameNS, value, function(b) { - function attrString() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - } - function attrStringNS() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - } - return b == null ? name.local ? attrNullNS : attrNull : (b += "", name.local ? attrStringNS : attrString); - }); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - var interpolate = d3_interpolateByName(name); - function styleNull() { - this.style.removeProperty(name); - } - return d3_transition_tween(this, "style." + name, value, function(b) { - function styleString() { - var a = getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - } - return b == null ? styleNull : (b += "", styleString); - }); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - return this.tween("style." + name, function(d, i) { - var f = tween.call(this, d, i, getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - }); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - return this.each("end.transition", function() { - var p; - if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node.__transition__[id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].delay = value.call(node, node.__data__, i, j) | 0; - } : (value |= 0, function(node) { - node.__transition__[id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j) | 0); - } : (value = Math.max(1, value | 0), function(node) { - node.__transition__[id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node.__transition__[id]; - type.call(node, node.__data__, i, j); - }); - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } else { - d3_selection_each(this, function(node) { - node.__transition__[id].event.on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = Object.create(node.__transition__[id0]); - transition.delay += transition.duration; - d3_transitionNode(node, i, id1, transition); - } - subgroup.push(node); - } - } - return d3_transition(subgroups, id1); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id; - if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node.__transition__[id].tween.remove(name); - } : function(node) { - node.__transition__[id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node.__transition__[id].tween.set(name, value); - })); - } - var d3_timer_id = 0, d3_timer_byId = {}, d3_timer_queue = null, d3_timer_interval, d3_timer_timeout; - d3.timer = function(callback, delay, then) { - if (arguments.length < 3) { - if (arguments.length < 2) delay = 0; else if (!isFinite(delay)) return; - then = Date.now(); - } - var timer = d3_timer_byId[callback.id]; - if (timer && timer.callback === callback) { - timer.then = then; - timer.delay = delay; - } else d3_timer_byId[callback.id = ++d3_timer_id] = d3_timer_queue = { - callback: callback, - then: then, - delay: delay, - next: d3_timer_queue - }; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - }; - function d3_timer_step() { - var elapsed, now = Date.now(), t1 = d3_timer_queue; - while (t1) { - elapsed = now - t1.then; - if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed); - t1 = t1.next; - } - var delay = d3_timer_flush() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - var elapsed, now = Date.now(), t1 = d3_timer_queue; - while (t1) { - elapsed = now - t1.then; - if (!t1.delay) t1.flush = t1.callback(elapsed); - t1 = t1.next; - } - d3_timer_flush(); - }; - function d3_timer_flush() { - var t0 = null, t1 = d3_timer_queue, then = Infinity; - while (t1) { - if (t1.flush) { - delete d3_timer_byId[t1.callback.id]; - t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next; - } else { - then = Math.min(then, t1.then + t1.delay); - t1 = (t0 = t1).next; - } - } - return then; - } - var d3_timer_frame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { - setTimeout(callback, 17); - }; - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0; - function d3_mousePoint(container, e) { - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0 && (window.scrollX || window.scrollY)) { - svg = d3.select(document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - if (d3_mouse_bug44083) { - point.x = e.pageX; - point.y = e.pageY; - } else { - point.x = e.clientX; - point.y = e.clientY; - } - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - function d3_noop() {} - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - if (nice = nice(x1 - x0)) { - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - } - return domain; - } - function d3_scale_niceDefault() { - return Math; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3.interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3.interpolate); - return scale; - } - function scale(x) { - return output(x); - } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3.interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m) { - return d3_scale_linearTickFormat(domain, m); - }; - scale.nice = function() { - d3_scale_nice(domain, d3_scale_linearNice); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(dx) { - dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1); - return dx && { - floor: function(x) { - return Math.floor(x / dx) * dx; - }, - ceil: function(x) { - return Math.ceil(x / dx) * dx; - } - }; - } - function d3_scale_linearTickRange(domain, m) { - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m) { - return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f"); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear(), d3_scale_logp); - }; - function d3_scale_log(linear, log) { - var pow = log.pow; - function scale(x) { - return linear(log(x)); - } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(pow); - log = x[0] < 0 ? d3_scale_logn : d3_scale_logp; - pow = log.pow; - linear.domain(x.map(log)); - return scale; - }; - scale.nice = function() { - linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault)); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(linear.domain()), ticks = []; - if (extent.every(isFinite)) { - var i = Math.floor(extent[0]), j = Math.ceil(extent[1]), u = pow(extent[0]), v = pow(extent[1]); - if (log === d3_scale_logn) { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k); - } else { - for (;i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); - } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (arguments.length < 2) format = d3_scale_logFormat; - if (!arguments.length) return format; - var k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12, - Math.floor) : (e = 1e-12, Math.ceil), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), log); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"); - function d3_scale_logp(x) { - return Math.log(x < 0 ? 0 : x) / Math.LN10; - } - function d3_scale_logn(x) { - return -Math.log(x > 0 ? 0 : -x) / Math.LN10; - } - d3_scale_logp.pow = function(x) { - return Math.pow(10, x); - }; - d3_scale_logn.pow = function(x) { - return -Math.pow(10, -x); - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1); - }; - function d3_scale_pow(linear, exponent) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); - } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(powb); - linear.domain(x.map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(scale.domain(), m); - }; - scale.tickFormat = function(m) { - return d3_scale_linearTickFormat(scale.domain(), m); - }; - scale.nice = function() { - return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - var domain = scale.domain(); - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - return scale.domain(domain); - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length]; - } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); - range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; - range = steps(start + Math.round(error / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf" ]; - var d3_category20 = [ "#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c", "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f", "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5" ]; - var d3_category20b = [ "#393b79", "#5254a3", "#6b6ecf", "#9c9ede", "#637939", "#8ca252", "#b5cf6b", "#cedb9c", "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#e7969c", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6" ]; - var d3_category20c = [ "#3182bd", "#6baed6", "#9ecae1", "#c6dbef", "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2", "#31a354", "#74c476", "#a1d99b", "#c7e9c0", "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb", "#636363", "#969696", "#bdbdbd", "#d9d9d9" ]; - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - function scale(x) { - if (isNaN(x = +x)) return NaN; - return range[d3.bisect(thresholds, x)]; - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.filter(function(d) { - return !isNaN(d); - }).sort(d3.ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - return range[d3.bisect(domain, x)]; - } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; - } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m) { - return d3_scale_linearTickFormat(domain, m); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg = {}; - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function arc() { - var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, - a0 = a1, a1 = da), a1 - a0), df = da < π ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); - return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; - } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcOffset = -π / 2, d3_svg_arcMax = 2 * π - 1e-6; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - function d3_svg_line(projection) { - var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; - } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - function d3_svg_lineX(d) { - return d[0]; - } - function d3_svg_lineY(d) { - return d[1]; - } - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.join("L"); - } - function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0 ]; - d3_svg_lineBasisBezier(path, px, py); - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - i = -1; - while (++i < 2) { - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (Math.abs(d) < 1e-6) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] + d3_svg_arcOffset; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_svg_lineX, x1 = d3_svg_lineX, y0 = 0, y1 = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = "bottom", tickMajorSize = 6, tickMinorSize = 6, tickEndSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_, tickSubdivide = 0; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var ticks = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain() : tickValues, tickFormat = tickFormat_ == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String : tickFormat_; - var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide), subtick = g.selectAll(".minor").data(subticks, String), subtickEnter = subtick.enter().insert("line", "g").attr("class", "tick minor").style("opacity", 1e-6), subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(), subtickUpdate = d3.transition(subtick).style("opacity", 1); - var tick = g.selectAll("g").data(ticks, String), tickEnter = tick.enter().insert("g", "path").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; - var range = d3_scaleRange(scale), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = d3.transition(path); - var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; - this.__chart__ = scale1; - path.enter().append("path").attr("class", "domain"); - tickEnter.append("line").attr("class", "tick"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); - switch (orient) { - case "bottom": - { - tickTransform = d3_svg_axisX; - subtickEnter.attr("y2", tickMinorSize); - subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize); - lineEnter.attr("y2", tickMajorSize); - textEnter.attr("y", Math.max(tickMajorSize, 0) + tickPadding); - lineUpdate.attr("x2", 0).attr("y2", tickMajorSize); - textUpdate.attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding); - text.attr("dy", ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); - break; - } - - case "top": - { - tickTransform = d3_svg_axisX; - subtickEnter.attr("y2", -tickMinorSize); - subtickUpdate.attr("x2", 0).attr("y2", -tickMinorSize); - lineEnter.attr("y2", -tickMajorSize); - textEnter.attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); - lineUpdate.attr("x2", 0).attr("y2", -tickMajorSize); - textUpdate.attr("x", 0).attr("y", -(Math.max(tickMajorSize, 0) + tickPadding)); - text.attr("dy", "0em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize); - break; - } - - case "left": - { - tickTransform = d3_svg_axisY; - subtickEnter.attr("x2", -tickMinorSize); - subtickUpdate.attr("x2", -tickMinorSize).attr("y2", 0); - lineEnter.attr("x2", -tickMajorSize); - textEnter.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)); - lineUpdate.attr("x2", -tickMajorSize).attr("y2", 0); - textUpdate.attr("x", -(Math.max(tickMajorSize, 0) + tickPadding)).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "end"); - pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize); - break; - } - - case "right": - { - tickTransform = d3_svg_axisY; - subtickEnter.attr("x2", tickMinorSize); - subtickUpdate.attr("x2", tickMinorSize).attr("y2", 0); - lineEnter.attr("x2", tickMajorSize); - textEnter.attr("x", Math.max(tickMajorSize, 0) + tickPadding); - lineUpdate.attr("x2", tickMajorSize).attr("y2", 0); - textUpdate.attr("x", Math.max(tickMajorSize, 0) + tickPadding).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "start"); - pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize); - break; - } - } - if (scale.ticks) { - tickEnter.call(tickTransform, scale0); - tickUpdate.call(tickTransform, scale1); - tickExit.call(tickTransform, scale1); - subtickEnter.call(tickTransform, scale0); - subtickUpdate.call(tickTransform, scale1); - subtickExit.call(tickTransform, scale1); - } else { - var dx = scale1.rangeBand() / 2, x = function(d) { - return scale1(d) + dx; - }; - tickEnter.call(tickTransform, x); - tickUpdate.call(tickTransform, x); - } - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x, y) { - if (!arguments.length) return tickMajorSize; - var n = arguments.length - 1; - tickMajorSize = +x; - tickMinorSize = n > 1 ? +y : tickMajorSize; - tickEndSize = n > 0 ? +arguments[n] : tickMajorSize; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function(x) { - if (!arguments.length) return tickSubdivide; - tickSubdivide = +x; - return axis; - }; - return axis; - }; - function d3_svg_axisX(selection, x) { - selection.attr("transform", function(d) { - return "translate(" + x(d) + ",0)"; - }); - } - function d3_svg_axisY(selection, y) { - selection.attr("transform", function(d) { - return "translate(0," + y(d) + ")"; - }); - } - function d3_svg_axisSubdivide(scale, ticks, m) { - subticks = []; - if (m && ticks.length > 1) { - var extent = d3_scaleExtent(scale.domain()), subticks, i = -1, n = ticks.length, d = (ticks[1] - ticks[0]) / ++m, j, v; - while (++i < n) { - for (j = m; --j > 0; ) { - if ((v = +ticks[i] - j * d) >= extent[0]) { - subticks.push(v); - } - } - } - for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1]; ) { - subticks.push(v); - } - } - return subticks; - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, resizes = d3_svg_brushResizes[0], extent = [ [ 0, 0 ], [ 0, 0 ] ], extentDomain; - function brush(g) { - g.each(function() { - var g = d3.select(this), bg = g.selectAll(".background").data([ 0 ]), fg = g.selectAll(".extent").data([ 0 ]), tz = g.selectAll(".resize").data(resizes, String), e; - g.style("pointer-events", "all").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - bg.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - fg.enter().append("rect").attr("class", "extent").style("cursor", "move"); - tz.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - tz.style("display", brush.empty() ? "none" : null); - tz.exit().remove(); - if (x) { - e = d3_scaleRange(x); - bg.attr("x", e[0]).attr("width", e[1] - e[0]); - redrawX(g); - } - if (y) { - e = d3_scaleRange(y); - bg.attr("y", e[0]).attr("height", e[1] - e[0]); - redrawY(g); - } - redraw(g); - }); - } - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + extent[+/e$/.test(d)][0] + "," + extent[+/^s/.test(d)][1] + ")"; - }); - } - function redrawX(g) { - g.select(".extent").attr("x", extent[0][0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", extent[1][0] - extent[0][0]); - } - function redrawY(g) { - g.select(".extent").attr("y", extent[0][1]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", extent[1][1] - extent[0][1]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), center, origin = mouse(), offset; - var w = d3.select(window).on("mousemove.brush", brushmove).on("mouseup.brush", brushend).on("touchmove.brush", brushmove).on("touchend.brush", brushend).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (dragging) { - origin[0] = extent[0][0] - origin[0]; - origin[1] = extent[0][1] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ extent[1 - ex][0] - origin[0], extent[1 - ey][1] - origin[1] ]; - origin[0] = extent[ex][0]; - origin[1] = extent[ey][1]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - d3_eventCancel(); - function mouse() { - var touches = d3.event.changedTouches; - return touches ? d3.touches(target, touches)[0] : d3.mouse(target); - } - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= extent[1][0]; - origin[1] -= extent[1][1]; - dragging = 2; - } - d3_eventCancel(); - } - } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += extent[1][0]; - origin[1] += extent[1][1]; - dragging = 0; - d3_eventCancel(); - } - } - function brushmove() { - var point = mouse(), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (extent[0][0] + extent[1][0]) / 2, (extent[0][1] + extent[1][1]) / 2 ]; - origin[0] = extent[+(point[0] < center[0])][0]; - origin[1] = extent[+(point[1] < center[1])][1]; - } else center = null; - } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); - } - } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], size = extent[1][i] - extent[0][i], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; - } - min = Math.max(r0, Math.min(r1, point[i])); - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - if (extent[0][i] !== min || extent[1][i] !== max) { - extentDomain = null; - extent[0][i] = min; - extent[1][i] = max; - return true; - } - } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - event_({ - type: "brushend" - }); - d3_eventCancel(); - } - } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - z = extentDomain || extent; - if (x) { - x0 = z[0][0], x1 = z[1][0]; - if (!extentDomain) { - x0 = extent[0][0], x1 = extent[1][0]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - y0 = z[0][1], y1 = z[1][1]; - if (!extentDomain) { - y0 = extent[0][1], y1 = extent[1][1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - extentDomain = [ [ 0, 0 ], [ 0, 0 ] ]; - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - extentDomain[0][0] = x0, extentDomain[1][0] = x1; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - extent[0][0] = x0 | 0, extent[1][0] = x1 | 0; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - extentDomain[0][1] = y0, extentDomain[1][1] = y1; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - extent[0][1] = y0 | 0, extent[1][1] = y1 | 0; - } - return brush; - }; - brush.clear = function() { - extentDomain = null; - extent[0][0] = extent[0][1] = extent[1][0] = extent[1][1] = 0; - return brush; - }; - brush.empty = function() { - return x && extent[0][0] === extent[1][0] || y && extent[0][1] === extent[1][1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - d3.behavior = {}; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null; - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", mousedown); - } - function mousedown() { - var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, offset, origin_ = point(), moved = 0; - var w = d3.select(window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true); - if (origin) { - offset = origin.apply(target, arguments); - offset = [ offset.x - origin_[0], offset.y - origin_[1] ]; - } else { - offset = [ 0, 0 ]; - } - if (touchId == null) d3_eventCancel(); - event_({ - type: "dragstart" - }); - function point() { - var p = target.parentNode; - return touchId != null ? d3.touches(p).filter(function(p) { - return p.identifier === touchId; - })[0] : d3.mouse(p); - } - function dragmove() { - if (!target.parentNode) return dragend(); - var p = point(), dx = p[0] - origin_[0], dy = p[1] - origin_[1]; - moved |= dx | dy; - origin_ = p; - d3_eventCancel(); - event_({ - type: "drag", - x: p[0] + offset[0], - y: p[1] + offset[1], - dx: dx, - dy: dy - }); - } - function dragend() { - event_({ - type: "dragend" - }); - if (moved) { - d3_eventCancel(); - if (d3.event.target === eventTarget) w.on("click.drag", click, true); - } - w.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", null); - } - function click() { - d3_eventCancel(); - w.on("click.drag", null); - } - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - d3.behavior.zoom = function() { - var translate = [ 0, 0 ], translate0, scale = 1, scale0, scaleExtent = d3_behavior_zoomInfinity, event = d3_eventDispatch(zoom, "zoom"), x0, x1, y0, y1, touchtime; - function zoom() { - this.on("mousedown.zoom", mousedown).on("mousewheel.zoom", mousewheel).on("mousemove.zoom", mousemove).on("DOMMouseScroll.zoom", mousewheel).on("dblclick.zoom", dblclick).on("touchstart.zoom", touchstart).on("touchmove.zoom", touchmove).on("touchend.zoom", touchstart); - } - zoom.translate = function(x) { - if (!arguments.length) return translate; - translate = x.map(Number); - rescale(); - return zoom; - }; - zoom.scale = function(x) { - if (!arguments.length) return scale; - scale = +x; - rescale(); - return zoom; - }; - zoom.scaleExtent = function(x) { - if (!arguments.length) return scaleExtent; - scaleExtent = x == null ? d3_behavior_zoomInfinity : x.map(Number); - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - translate = [ 0, 0 ]; - scale = 1; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - translate = [ 0, 0 ]; - scale = 1; - return zoom; - }; - function location(p) { - return [ (p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale ]; - } - function point(l) { - return [ l[0] * scale + translate[0], l[1] * scale + translate[1] ]; - } - function scaleTo(s) { - scale = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - translate[0] += p[0] - l[0]; - translate[1] += p[1] - l[1]; - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - translate[0]) / scale; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - translate[1]) / scale; - }).map(y0.invert)); - } - function dispatch(event) { - rescale(); - d3.event.preventDefault(); - event({ - type: "zoom", - scale: scale, - translate: translate - }); - } - function mousedown() { - var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, moved = 0, w = d3.select(window).on("mousemove.zoom", mousemove).on("mouseup.zoom", mouseup), l = location(d3.mouse(target)); - window.focus(); - d3_eventCancel(); - function mousemove() { - moved = 1; - translateTo(d3.mouse(target), l); - dispatch(event_); - } - function mouseup() { - if (moved) d3_eventCancel(); - w.on("mousemove.zoom", null).on("mouseup.zoom", null); - if (moved && d3.event.target === eventTarget) w.on("click.zoom", click, true); - } - function click() { - d3_eventCancel(); - w.on("click.zoom", null); - } - } - function mousewheel() { - if (!translate0) translate0 = location(d3.mouse(this)); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * scale); - translateTo(d3.mouse(this), translate0); - dispatch(event.of(this, arguments)); - } - function mousemove() { - translate0 = null; - } - function dblclick() { - var p = d3.mouse(this), l = location(p), k = Math.log(scale) / Math.LN2; - scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); - translateTo(p, l); - dispatch(event.of(this, arguments)); - } - function touchstart() { - var touches = d3.touches(this), now = Date.now(); - scale0 = scale; - translate0 = {}; - touches.forEach(function(t) { - translate0[t.identifier] = location(t); - }); - d3_eventCancel(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0], l = location(touches[0]); - scaleTo(scale * 2); - translateTo(p, l); - dispatch(event.of(this, arguments)); - } - touchtime = now; - } - } - function touchmove() { - var touches = d3.touches(this), p0 = touches[0], l0 = translate0[p0.identifier]; - if (p1 = touches[1]) { - var p1, l1 = translate0[p1.identifier]; - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(d3.event.scale * scale0); - } - translateTo(p0, l0); - touchtime = null; - dispatch(event.of(this, arguments)); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomDiv, d3_behavior_zoomInfinity = [ 0, Infinity ]; - function d3_behavior_zoomDelta() { - if (!d3_behavior_zoomDiv) { - d3_behavior_zoomDiv = d3.select("body").append("div").style("visibility", "hidden").style("top", 0).style("height", 0).style("width", 0).style("overflow-y", "scroll").append("div").style("height", "2000px").node().parentNode; - } - var e = d3.event, delta; - try { - d3_behavior_zoomDiv.scrollTop = 1e3; - d3_behavior_zoomDiv.dispatchEvent(e); - delta = 1e3 - d3_behavior_zoomDiv.scrollTop; - } catch (error) { - delta = e.wheelDelta || -e.detail * 5; - } - return delta; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - k = (2 * π - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); - } - } - } - if (sortChords) resort(); - } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); - } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, gravity = .1, theta = .8, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dn = 1 / Math.sqrt(dx * dx + dy * dy); - if ((x2 - x1) * dn < theta) { - var k = quad.charge * dn * dn; - node.px -= dx * k; - node.py -= dy * k; - return true; - } - if (quad.point && isFinite(dn)) { - var k = quad.pointCharge * dn * dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - force.tick = function() { - if ((alpha *= .99) < .005) { - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = d3_functor(x); - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = d3_functor(x); - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return theta; - theta = x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - if (alpha) { - if (x > 0) alpha = x; else alpha = 0; - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - d3.timer(force.tick); - } - return force; - }; - force.start = function() { - var i, j, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - distances = []; - strengths = []; - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - distances[i] = linkDistance.call(this, o, i); - strengths[i] = linkStrength.call(this, o, i); - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - charges = []; - if (typeof charge === "function") { - for (i = 0; i < n; ++i) { - charges[i] = +charge.call(this, nodes[i], i); - } - } else { - for (i = 0; i < n; ++i) { - charges[i] = charge; - } - } - function position(dimension, size) { - var neighbors = neighbor(i), j = -1, m = neighbors.length, x; - while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x; - return Math.random() * size; - } - function neighbor() { - if (!neighbors) { - neighbors = []; - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - return neighbors[i]; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart", d3_layout_forceDragstart).on("drag", dragmove).on("dragend", d3_layout_forceDragend); - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); - } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= 1; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= 3; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - function d3_layout_forceLinkDistance() { - return 20; - } - function d3_layout_forceLinkStrength() { - return 1; - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = 2 * π; - function pie(data) { - var values = data.map(function(d, i) { - return +value.call(pie, d, i); - }); - var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); - var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - startAngle) / d3.sum(values); - var index = d3.range(data.length); - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - var arcs = []; - index.forEach(function(i) { - var d; - arcs[i] = { - data: data[i], - value: d = values[i], - startAngle: a, - endAngle: a += d * k - }; - }); - return arcs; - } - pie.value = function(x) { - if (!arguments.length) return value; - value = x; - return pie; - }; - pie.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return pie; - }; - pie.startAngle = function(x) { - if (!arguments.length) return startAngle; - startAngle = x; - return pie; - }; - pie.endAngle = function(x) { - if (!arguments.length) return endAngle; - endAngle = x; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var n = series.length, m = series[0].length, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - return data; - } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - return bins; - } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function recurse(node, depth, nodes) { - var childs = children.call(hierarchy, node, depth); - node.depth = depth; - nodes.push(node); - if (childs && (n = childs.length)) { - var i = -1, n, c = node.children = [], v = 0, j = depth + 1, d; - while (++i < n) { - d = recurse(childs[i], j, nodes); - d.parent = node; - c.push(d); - v += d.value; - } - if (sort) c.sort(sort); - if (value) node.value = v; - } else if (value) { - node.value = +value.call(hierarchy, node, depth) || 0; - } - return node; - } - function revalue(node, depth) { - var children = node.children, v = 0; - if (children && (n = children.length)) { - var i = -1, n, j = depth + 1; - while (++i < n) v += revalue(children[i], j); - } else if (value) { - v = +value.call(hierarchy, node, depth) || 0; - } - if (value) node.value = v; - return v; - } - function hierarchy(d) { - var nodes = []; - recurse(d, 0, nodes); - return nodes; - } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - revalue(root, 0); - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ]; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0]; - root.x = 0; - root.y = 0; - d3_layout_treeVisitAfter(root, function(d) { - d.r = Math.sqrt(d.value); - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - var w = size[0], h = size[1], k = Math.max(2 * root.r / w, 2 * root.r / h); - if (padding > 0) { - var dr = padding * k / 2; - d3_layout_treeVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - d3_layout_treeVisitAfter(root, function(d) { - d.r -= dr; - }); - k = Math.max(2 * root.r / w, 2 * root.r / h); - } - d3_layout_packTransform(root, w / 2, h / 2, 1 / k); - return nodes; - } - pack.size = function(x) { - if (!arguments.length) return size; - size = x; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return dr * dr - dx * dx - dy * dy > .001; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ]; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_treeVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_treeVisitAfter(root, function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; - } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return size; - size = x; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ]; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0]; - function firstWalk(node, previousSibling) { - var children = node.children, layout = node._tree; - if (children && (n = children.length)) { - var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; - while (++i < n) { - child = children[i]; - firstWalk(child, previousChild); - ancestor = apportion(child, previousChild, ancestor); - previousChild = child; - } - d3_layout_treeShift(node); - var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - layout.mod = layout.prelim - midpoint; - } else { - layout.prelim = midpoint; - } - } else { - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - } - } - } - function secondWalk(node, x) { - node.x = node._tree.prelim + x; - var children = node.children; - if (children && (n = children.length)) { - var i = -1, n; - x += node._tree.mod; - while (++i < n) { - secondWalk(children[i], x); - } - } - } - function apportion(node, previousSibling, ancestor) { - if (previousSibling) { - var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop._tree.ancestor = node; - shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); - sip += shift; - sop += shift; - } - sim += vim._tree.mod; - sip += vip._tree.mod; - som += vom._tree.mod; - sop += vop._tree.mod; - } - if (vim && !d3_layout_treeRight(vop)) { - vop._tree.thread = vim; - vop._tree.mod += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom._tree.thread = vip; - vom._tree.mod += sip - som; - ancestor = node; - } - } - return ancestor; - } - d3_layout_treeVisitAfter(root, function(node, previousSibling) { - node._tree = { - ancestor: node, - prelim: 0, - mod: 0, - change: 0, - shift: 0, - number: previousSibling ? previousSibling._tree.number + 1 : 0 - }; - }); - firstWalk(root); - secondWalk(root, -root._tree.prelim); - var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; - d3_layout_treeVisitAfter(root, function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = node.depth / y1 * size[1]; - delete node._tree; - }); - return nodes; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return size; - size = x; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(node) { - var children = node.children; - return children && children.length ? children[0] : node._tree.thread; - } - function d3_layout_treeRight(node) { - var children = node.children, n; - return children && (n = children.length) ? children[n - 1] : node._tree.thread; - } - function d3_layout_treeSearch(node, compare) { - var children = node.children; - if (children && (n = children.length)) { - var child, n, i = -1; - while (++i < n) { - if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { - node = child; - } - } - } - return node; - } - function d3_layout_treeRightmost(a, b) { - return a.x - b.x; - } - function d3_layout_treeLeftmost(a, b) { - return b.x - a.x; - } - function d3_layout_treeDeepest(a, b) { - return a.depth - b.depth; - } - function d3_layout_treeVisitAfter(node, callback) { - function visit(node, previousSibling) { - var children = node.children; - if (children && (n = children.length)) { - var child, previousChild = null, i = -1, n; - while (++i < n) { - child = children[i]; - visit(child, previousChild); - previousChild = child; - } - } - callback(node, previousSibling); - } - visit(node, null); - } - function d3_layout_treeShift(node) { - var shift = 0, change = 0, children = node.children, i = children.length, child; - while (--i >= 0) { - child = children[i]._tree; - child.prelim += shift; - child.mod += shift; - shift += child.shift + (change += child.change); - } - } - function d3_layout_treeMove(ancestor, node, shift) { - ancestor = ancestor._tree; - node = node._tree; - var change = shift / (node.number - ancestor.number); - ancestor.change += change; - node.change -= change; - node.shift += shift; - node.prelim += shift; - node.mod += shift; - } - function d3_layout_treeAncestor(vim, node, ancestor) { - return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" || mode === "slice-dice" && node.depth & 1 ? rect.dy : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - function d3_dsv(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, callback) { - return d3.xhr(url, mimeType, callback).response(response); - } - function response(request) { - return dsv.parse(request.responseText); - } - dsv.parse = function(text) { - var o; - return dsv.parseRows(text, function(row) { - if (o) return o(row); - o = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.substring(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.substring(j, I - k); - } - return text.substring(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && !(a = f(a, n++))) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - } - d3.csv = d3_dsv(",", "text/csv"); - d3.tsv = d3_dsv(" ", "text/tab-separated-values"); - d3.geo = {}; - d3.geo.stream = function(object, listener) { - if (d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - var coordinate = object.coordinates; - listener.point(coordinate[0], coordinate[1]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate; - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), Math.asin(Math.max(-1, Math.min(1, cartesian[2]))) ]; - } - function d3_geo_sphericalEqual(a, b) { - return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_resample(project) { - var δ2 = .5, maxDepth = 16; - function resample(stream) { - var λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = polygonLineStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function polygonLineStart() { - var λ00, φ00, x00, y00, a00, b00, c00; - lineStart(); - resample.point = function(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - }; - resample.lineEnd = function() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - }; - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.albers().rotate([ 160, 0 ]).center([ 0, 60 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.albers().rotate([ 160, 0 ]).center([ 0, 20 ]).parallels([ 8, 18 ]); - var puertoRico = d3.geo.albers().rotate([ 60, 0 ]).center([ 0, 10 ]).parallels([ 8, 18 ]); - function albersUsa(coordinates) { - return projection(coordinates)(coordinates); - } - function projection(point) { - var lon = point[0], lat = point[1]; - return lat > 50 ? alaska : lon < -140 ? hawaii : lat < 21 ? puertoRico : lower48; - } - albersUsa.scale = function(x) { - if (!arguments.length) return lower48.scale(); - lower48.scale(x); - alaska.scale(x * .6); - hawaii.scale(x); - puertoRico.scale(x * 1.5); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(x) { - if (!arguments.length) return lower48.translate(); - var dz = lower48.scale(), dx = x[0], dy = x[1]; - lower48.translate(x); - alaska.translate([ dx - .4 * dz, dy + .17 * dz ]); - hawaii.translate([ dx - .19 * dz, dy + .2 * dz ]); - puertoRico.translate([ dx + .58 * dz, dy + .43 * dz ]); - return albersUsa; - }; - return albersUsa.scale(lower48.scale()); - }; - function d3_geo_albers(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; - function albers(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; - } - albers.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ Math.atan2(x, ρ0_y) / n, Math.asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; - }; - return albers; - } - (d3.geo.albers = function() { - var φ0 = 29.5 * d3_radians, φ1 = 45.5 * d3_radians, m = d3_geo_projectionMutator(d3_geo_albers), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 * d3_degrees, φ1 * d3_degrees ]; - return m(φ0 = _[0] * d3_radians, φ1 = _[1] * d3_radians); - }; - return p.rotate([ 98, 0 ]).center([ 0, 38 ]).scale(1e3); - }).raw = d3_geo_albers; - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(ρ) { - return 2 * Math.asin(ρ / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - d3.geo.bounds = d3_geo_bounds(); - function d3_geo_bounds(projection) { - var x0, y0, x1, y1; - var bound = { - point: boundPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - bound.lineEnd = boundPolygonLineEnd; - }, - polygonEnd: function() { - bound.point = boundPoint; - } - }; - var projectBound = projection ? projection.stream(bound) : bound; - function boundPoint(x, y) { - if (x < x0) x0 = x; - if (x > x1) x1 = x; - if (y < y0) y0 = y; - if (y > y1) y1 = y; - } - function boundPolygonLineEnd() { - bound.point = bound.lineEnd = d3_noop; - } - return function(feature) { - y1 = x1 = -(x0 = y0 = Infinity); - d3.geo.stream(feature, projectBound); - return [ [ x0, y0 ], [ x1, y1 ] ]; - }; - } - d3.geo.centroid = function(object) { - d3_geo_centroidDimension = d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; - d3.geo.stream(object, d3_geo_centroid); - var m; - if (d3_geo_centroidW && Math.abs(m = Math.sqrt(d3_geo_centroidX * d3_geo_centroidX + d3_geo_centroidY * d3_geo_centroidY + d3_geo_centroidZ * d3_geo_centroidZ)) > ε) { - return [ Math.atan2(d3_geo_centroidY, d3_geo_centroidX) * d3_degrees, Math.asin(Math.max(-1, Math.min(1, d3_geo_centroidZ / m))) * d3_degrees ]; - } - }; - var d3_geo_centroidDimension, d3_geo_centroidW, d3_geo_centroidX, d3_geo_centroidY, d3_geo_centroidZ; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroidDimension = 2; - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - if (d3_geo_centroidDimension) return; - ++d3_geo_centroidW; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidX += (cosφ * Math.cos(λ) - d3_geo_centroidX) / d3_geo_centroidW; - d3_geo_centroidY += (cosφ * Math.sin(λ) - d3_geo_centroidY) / d3_geo_centroidW; - d3_geo_centroidZ += (Math.sin(φ) - d3_geo_centroidZ) / d3_geo_centroidW; - } - function d3_geo_centroidRingStart() { - var λ00, φ00; - if (d3_geo_centroidDimension < 2) { - d3_geo_centroidDimension = 2; - d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; - } - d3_geo_centroidDimension = 1; - d3_geo_centroidLineStart(); - d3_geo_centroidDimension = 2; - var linePoint = d3_geo_centroid.point; - d3_geo_centroid.point = function(λ, φ) { - linePoint(λ00 = λ, φ00 = φ); - }; - d3_geo_centroid.lineEnd = function() { - d3_geo_centroid.point(λ00, φ00); - d3_geo_centroidLineEnd(); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - }; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - if (d3_geo_centroidDimension !== 1) { - if (d3_geo_centroidDimension < 1) { - d3_geo_centroidDimension = 1; - d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; - } else return; - } - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW += w; - d3_geo_centroidX += w * (x0 + (x0 = x)); - d3_geo_centroidY += w * (y0 + (y0 = y)); - d3_geo_centroidZ += w * (z0 + (z0 = z)); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(center[0] * d3_radians, center[1] * d3_radians, 0), ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radians, precision) { - var cr = Math.cos(radians), sr = Math.sin(radians); - return function(from, to, direction, listener) { - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * 2 * π; - } else { - from = radians + direction * 2 * π; - to = radians; - } - var point; - for (var step = direction * precision, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = Math.acos(Math.max(-1, Math.min(1, -a[1]))); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - function d3_geo_clip(pointVisible, clipLine, interpolate) { - return function(listener) { - var line = clipLine(listener); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - invisible = false; - invisibleArea = visibleArea = 0; - segments = []; - listener.polygonStart(); - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - if (segments.length) { - d3_geo_clipPolygon(segments, interpolate, listener); - } else if (visibleArea < -ε || invisible && invisibleArea < -ε) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - listener.polygonEnd(); - segments = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - if (pointVisible(λ, φ)) listener.point(λ, φ); - } - function pointLine(λ, φ) { - line.point(λ, φ); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments, visibleArea, invisibleArea, invisible; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), ring; - function pointRing(λ, φ) { - ringListener.point(λ, φ); - ring.push([ λ, φ ]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - if (!n) { - invisible = true; - invisibleArea += d3_geo_clipAreaRing(ring, -1); - ring = null; - return; - } - ring = null; - if (clean & 1) { - segment = ringSegments[0]; - visibleArea += d3_geo_clipAreaRing(segment, 1); - var n = segment.length - 1, i = -1, point; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipPolygon(segments, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - var n = segment.length; - if (n <= 1) return; - var p0 = segment[0], p1 = segment[n - 1], a = { - point: p0, - points: segment, - other: null, - visited: false, - entry: true, - subject: true - }, b = { - point: p0, - points: [ p0 ], - other: a, - visited: false, - entry: false, - subject: false - }; - a.other = b; - subject.push(a); - clip.push(b); - a = { - point: p1, - points: [ p1 ], - other: null, - visited: false, - entry: false, - subject: true - }; - b = { - point: p1, - points: [ p1 ], - other: a, - visited: false, - entry: true, - subject: false - }; - a.other = b; - subject.push(a); - clip.push(b); - }); - clip.sort(d3_geo_clipSort); - d3_geo_clipLinkCircular(subject); - d3_geo_clipLinkCircular(clip); - if (!subject.length) return; - var start = subject[0], current, points, point; - while (1) { - current = start; - while (current.visited) if ((current = current.next) === start) return; - points = current.points; - listener.lineStart(); - do { - current.visited = current.other.visited = true; - if (current.entry) { - if (current.subject) { - for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.point, current.next.point, 1, listener); - } - current = current.next; - } else { - if (current.subject) { - points = current.prev.points; - for (var i = points.length; --i >= 0; ) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.point, current.prev.point, -1, listener); - } - current = current.prev; - } - current = current.other; - points = current.points; - } while (!current.visited); - listener.lineEnd(); - } - } - function d3_geo_clipLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.next = b = array[i]; - b.prev = a; - a = b; - } - a.next = b = array[0]; - b.prev = a; - } - function d3_geo_clipSort(a, b) { - return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]); - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - } - }; - } - function d3_geo_clipAreaRing(ring, invisible) { - if (!(n = ring.length)) return 0; - var n, i = 0, area = 0, p = ring[0], λ = p[0], φ = p[1], cosφ = Math.cos(φ), x0 = Math.atan2(invisible * Math.sin(λ) * cosφ, Math.sin(φ)), y0 = 1 - invisible * Math.cos(λ) * cosφ, x1 = x0, x, y; - while (++i < n) { - p = ring[i]; - cosφ = Math.cos(φ = p[1]); - x = Math.atan2(invisible * Math.sin(λ = p[0]) * cosφ, Math.sin(φ)); - y = 1 - invisible * Math.cos(λ) * cosφ; - if (Math.abs(y0 - 2) < ε && Math.abs(y - 2) < ε) continue; - if (Math.abs(y) < ε || Math.abs(y0) < ε) {} else if (Math.abs(Math.abs(x - x0) - π) < ε) { - if (y + y0 > 2) area += 4 * (x - x0); - } else if (Math.abs(y0 - 2) < ε) area += 4 * (x - x1); else area += ((3 * π + x - x0) % (2 * π) - π) * (y0 + y); - x1 = x0, x0 = x, y0 = y; - } - return area; - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, dλ = Math.abs(λ1 - λ0); - if (Math.abs(dλ - π) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { - if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * π / 2; - listener.point(-π, φ); - listener.point(0, φ); - listener.point(π, φ); - listener.point(π, 0); - listener.point(π, -φ); - listener.point(0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (Math.abs(from[0] - to[0]) > ε) { - var s = (from[0] < to[0] ? 1 : -1) * π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - function d3_geo_clipCircle(degrees) { - var radians = degrees * d3_radians, cr = Math.cos(radians), interpolate = d3_geo_circleInterpolate(radians, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ); - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v0 = v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) listener.point(point1[0], point1[1]); - point0 = point1; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b) { - var pa = d3_geo_cartesian(a, 0), pb = d3_geo_cartesian(b, 0); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t = Math.sqrt(w * w - uu * (d3_geo_cartesianDot(A, A) - 1)), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - return d3_geo_spherical(q); - } - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), a.invert(x[0], x[1]); - }; - return compose; - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular).scale(250 / π); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - d3.geo.graticule = function() { - var x1, x0, y1, y0, dx = 22.5, dy = dx, x, y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(x).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ x(x0).concat(y(y1).slice(1), x(x1).reverse().slice(1), y(y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, precision); - y = d3_geo_graticuleY(x0, x1, precision); - return graticule; - }; - return graticule.extent([ [ -180 + ε, -90 + ε ], [ 180 - ε, 90 - ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))), k = 1 / Math.sin(d); - function interpolate(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) / d3_radians, Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_radians ]; - } - interpolate.distance = d; - return interpolate; - } - d3.geo.greatArc = function() { - var source = d3_source, s, target = d3_target, t, precision = 6 * d3_radians, interpolate; - function greatArc() { - var p0 = s || source.apply(this, arguments), p1 = t || target.apply(this, arguments), i = interpolate || d3.geo.interpolate(p0, p1), t = 0, dt = precision / i.distance, coordinates = [ p0 ]; - while ((t += dt) < 1) coordinates.push(i(t)); - coordinates.push(p1); - return { - type: "LineString", - coordinates: coordinates - }; - } - greatArc.distance = function() { - return (interpolate || d3.geo.interpolate(s || source.apply(this, arguments), t || target.apply(this, arguments))).distance; - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, s = typeof _ === "function" ? null : _; - interpolate = s && t ? d3.geo.interpolate(s, t) : null; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, t = typeof _ === "function" ? null : _; - interpolate = s && t ? d3.geo.interpolate(s, t) : null; - return greatArc; - }; - greatArc.precision = function(_) { - if (!arguments.length) return precision / d3_radians; - precision = _ * d3_radians; - return greatArc; - }; - return greatArc; - }; - function d3_geo_mercator(λ, φ) { - return [ λ / (2 * π), Math.max(-.5, Math.min(+.5, Math.log(Math.tan(π / 4 + φ / 2)) / (2 * π))) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ 2 * π * x, 2 * Math.atan(Math.exp(2 * π * y)) - π / 2 ]; - }; - (d3.geo.mercator = function() { - return d3_geo_projection(d3_geo_mercator).scale(500); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream; - function path(object) { - if (object) d3.geo.stream(object, projectStream(contextStream.pointRadius(typeof pointRadius === "function" ? +pointRadius.apply(this, arguments) : pointRadius))); - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidDimension = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ ? [ d3_geo_centroidX / d3_geo_centroidZ, d3_geo_centroidY / d3_geo_centroidZ ] : undefined; - }; - path.bounds = function(object) { - return d3_geo_bounds(projection)(object); - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return path; - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - return path; - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : +_; - return path; - }; - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + +2 * radius + "z"; - } - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(λ, φ) { - return project([ λ * d3_degrees, φ * d3_degrees ]); - }); - return function(stream) { - stream = resample(stream); - return { - point: function(λ, φ) { - stream.point(λ * d3_radians, φ * d3_radians); - }, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - }; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x, y); - context.arc(x, y, pointRadius, 0, 2 * π); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - if (d3_geo_centroidDimension) return; - d3_geo_centroidX += x; - d3_geo_centroidY += y; - ++d3_geo_centroidZ; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - if (d3_geo_centroidDimension !== 1) { - if (d3_geo_centroidDimension < 1) { - d3_geo_centroidDimension = 1; - d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; - } else return; - } - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - x0 = x, y0 = y; - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX += z * (x0 + x) / 2; - d3_geo_centroidY += z * (y0 + y) / 2; - d3_geo_centroidZ += z; - x0 = x, y0 = y; - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - if (d3_geo_centroidDimension < 2) { - d3_geo_centroidDimension = 2; - d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0; - } - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - var z = y0 * x - x0 * y; - d3_geo_centroidX += z * (x0 + x); - d3_geo_centroidY += z * (y0 + y); - d3_geo_centroidZ += z * 3; - x0 = x, y0 = y; - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRing; - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * π; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRing = 0; - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - d3_geo_areaSum += d3_geo_areaRing < 0 ? 4 * π + d3_geo_areaRing : d3_geo_areaRing; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ1, λ0, φ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ1 = λ0 = (λ00 = λ) * d3_radians, φ0 = (φ00 = φ) * d3_radians, cosφ0 = Math.cos(φ0), - sinφ0 = Math.sin(φ0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians, φ *= d3_radians; - if (Math.abs(Math.abs(φ0) - π / 2) < ε && Math.abs(Math.abs(φ) - π / 2) < ε) return; - var cosφ = Math.cos(φ), sinφ = Math.sin(φ); - if (Math.abs(φ0 - π / 2) < ε) d3_geo_areaRing += (λ - λ1) * 2; else { - var dλ = λ - λ0, cosdλ = Math.cos(dλ), d = Math.atan2(Math.sqrt((d = cosφ * Math.sin(dλ)) * d + (d = cosφ0 * sinφ - sinφ0 * cosφ * cosdλ) * d), sinφ0 * sinφ + cosφ0 * cosφ * cosdλ), s = (d + π + φ0 + φ) / 4; - d3_geo_areaRing += (dλ < 0 && dλ > -π || dλ > π ? -4 : 4) * Math.atan(Math.sqrt(Math.abs(Math.tan(s) * Math.tan(s - d / 2) * Math.tan(s - π / 4 - φ0 / 2) * Math.tan(s - π / 4 - φ / 2)))); - } - λ1 = λ0, λ0 = λ, φ0 = φ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, clip = d3_geo_clipAntimeridian, clipAngle = null; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(stream) { - return d3_geo_projectionRadiansRotate(rotate, clip(projectResample(stream))); - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - clip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle(clipAngle = +_); - return projection; - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadiansRotate(rotate, stream) { - return { - point: function(x, y) { - y = rotate(x * d3_radians, y * d3_radians), x = y[0]; - stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]); - }, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - } - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_equirectangular; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), Math.asin(Math.max(-1, Math.min(1, k * cosδγ + y * sinδγ))) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), Math.asin(Math.max(-1, Math.min(1, k * cosδφ - x * sinδφ))) ]; - }; - return rotation; - } - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(ρ) { - return 2 * Math.atan(ρ); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; - }; - return azimuthal; - } - d3.geom = {}; - d3.geom.hull = function(vertices) { - if (vertices.length < 3) return []; - var len = vertices.length, plen = len - 1, points = [], stack = [], i, j, h = 0, x1, y1, x2, y2, u, v, a, sp; - for (i = 1; i < len; ++i) { - if (vertices[i][1] < vertices[h][1]) { - h = i; - } else if (vertices[i][1] == vertices[h][1]) { - h = vertices[i][0] < vertices[h][0] ? i : h; - } - } - for (i = 0; i < len; ++i) { - if (i === h) continue; - y1 = vertices[i][1] - vertices[h][1]; - x1 = vertices[i][0] - vertices[h][0]; - points.push({ - angle: Math.atan2(y1, x1), - index: i - }); - } - points.sort(function(a, b) { - return a.angle - b.angle; - }); - a = points[0].angle; - v = points[0].index; - u = 0; - for (i = 1; i < plen; ++i) { - j = points[i].index; - if (a == points[i].angle) { - x1 = vertices[v][0] - vertices[h][0]; - y1 = vertices[v][1] - vertices[h][1]; - x2 = vertices[j][0] - vertices[h][0]; - y2 = vertices[j][1] - vertices[h][1]; - if (x1 * x1 + y1 * y1 >= x2 * x2 + y2 * y2) { - points[i].index = -1; - } else { - points[u].index = -1; - a = points[i].angle; - u = i; - v = j; - } - } else { - a = points[i].angle; - u = i; - v = j; - } - } - stack.push(h); - for (i = 0, j = 0; i < 2; ++j) { - if (points[j].index !== -1) { - stack.push(points[j].index); - i++; - } - } - sp = stack.length; - for (;j < plen; ++j) { - if (points[j].index === -1) continue; - while (!d3_geom_hullCCW(stack[sp - 2], stack[sp - 1], points[j].index, vertices)) { - --sp; - } - stack[sp++] = points[j].index; - } - var poly = []; - for (i = 0; i < sp; ++i) { - poly.push(vertices[stack[i]]); - } - return poly; - }; - function d3_geom_hullCCW(i1, i2, i3, v) { - var t, a, b, c, d, e, f; - t = v[i1]; - a = t[0]; - b = t[1]; - t = v[i2]; - c = t[0]; - d = t[1]; - t = v[i3]; - e = t[0]; - f = t[1]; - return (f - b) * (c - a) - (d - b) * (e - a) > 0; - } - d3.geom.polygon = function(coordinates) { - coordinates.area = function() { - var i = 0, n = coordinates.length, area = coordinates[n - 1][1] * coordinates[0][0] - coordinates[n - 1][0] * coordinates[0][1]; - while (++i < n) { - area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][1]; - } - return area * .5; - }; - coordinates.centroid = function(k) { - var i = -1, n = coordinates.length, x = 0, y = 0, a, b = coordinates[n - 1], c; - if (!arguments.length) k = -1 / (6 * coordinates.area()); - while (++i < n) { - a = b; - b = coordinates[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; - }; - coordinates.clip = function(subject) { - var input, i = -1, n = coordinates.length, j, m, a = coordinates[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = coordinates[i]; - c = input[(m = input.length) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - a = b; - } - return subject; - }; - return coordinates; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - d3.geom.voronoi = function(vertices) { - var polygons = vertices.map(function() { - return []; - }), Z = 1e6; - d3_voronoi_tessellate(vertices, function(e) { - var s1, s2, x1, x2, y1, y2; - if (e.a === 1 && e.b >= 0) { - s1 = e.ep.r; - s2 = e.ep.l; - } else { - s1 = e.ep.l; - s2 = e.ep.r; - } - if (e.a === 1) { - y1 = s1 ? s1.y : -Z; - x1 = e.c - e.b * y1; - y2 = s2 ? s2.y : Z; - x2 = e.c - e.b * y2; - } else { - x1 = s1 ? s1.x : -Z; - y1 = e.c - e.a * x1; - x2 = s2 ? s2.x : Z; - y2 = e.c - e.a * x2; - } - var v1 = [ x1, y1 ], v2 = [ x2, y2 ]; - polygons[e.region.l.index].push(v1, v2); - polygons[e.region.r.index].push(v1, v2); - }); - polygons = polygons.map(function(polygon, i) { - var cx = vertices[i][0], cy = vertices[i][1], angle = polygon.map(function(v) { - return Math.atan2(v[0] - cx, v[1] - cy); - }); - return d3.range(polygon.length).sort(function(a, b) { - return angle[a] - angle[b]; - }).filter(function(d, i, order) { - return !i || angle[d] - angle[order[i - 1]] > ε; - }).map(function(d) { - return polygon[d]; - }); - }); - polygons.forEach(function(polygon, i) { - var n = polygon.length; - if (!n) return polygon.push([ -Z, -Z ], [ -Z, Z ], [ Z, Z ], [ Z, -Z ]); - if (n > 2) return; - var p0 = vertices[i], p1 = polygon[0], p2 = polygon[1], x0 = p0[0], y0 = p0[1], x1 = p1[0], y1 = p1[1], x2 = p2[0], y2 = p2[1], dx = Math.abs(x2 - x1), dy = y2 - y1; - if (Math.abs(dy) < ε) { - var y = y0 < y1 ? -Z : Z; - polygon.push([ -Z, y ], [ Z, y ]); - } else if (dx < ε) { - var x = x0 < x1 ? -Z : Z; - polygon.push([ x, -Z ], [ x, Z ]); - } else { - var y = (x2 - x1) * (y1 - y0) < (x1 - x0) * (y2 - y1) ? Z : -Z, z = Math.abs(dy) - dx; - if (Math.abs(z) < ε) { - polygon.push([ dy < 0 ? y : -y, y ]); - } else { - if (z > 0) y *= -1; - polygon.push([ -Z, y ], [ Z, y ]); - } - } - }); - return polygons; - }; - var d3_voronoi_opposite = { - l: "r", - r: "l" - }; - function d3_voronoi_tessellate(vertices, callback) { - var Sites = { - list: vertices.map(function(v, i) { - return { - index: i, - x: v[0], - y: v[1] - }; - }).sort(function(a, b) { - return a.y < b.y ? -1 : a.y > b.y ? 1 : a.x < b.x ? -1 : a.x > b.x ? 1 : 0; - }), - bottomSite: null - }; - var EdgeList = { - list: [], - leftEnd: null, - rightEnd: null, - init: function() { - EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l"); - EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l"); - EdgeList.leftEnd.r = EdgeList.rightEnd; - EdgeList.rightEnd.l = EdgeList.leftEnd; - EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd); - }, - createHalfEdge: function(edge, side) { - return { - edge: edge, - side: side, - vertex: null, - l: null, - r: null - }; - }, - insert: function(lb, he) { - he.l = lb; - he.r = lb.r; - lb.r.l = he; - lb.r = he; - }, - leftBound: function(p) { - var he = EdgeList.leftEnd; - do { - he = he.r; - } while (he != EdgeList.rightEnd && Geom.rightOf(he, p)); - he = he.l; - return he; - }, - del: function(he) { - he.l.r = he.r; - he.r.l = he.l; - he.edge = null; - }, - right: function(he) { - return he.r; - }, - left: function(he) { - return he.l; - }, - leftRegion: function(he) { - return he.edge == null ? Sites.bottomSite : he.edge.region[he.side]; - }, - rightRegion: function(he) { - return he.edge == null ? Sites.bottomSite : he.edge.region[d3_voronoi_opposite[he.side]]; - } - }; - var Geom = { - bisect: function(s1, s2) { - var newEdge = { - region: { - l: s1, - r: s2 - }, - ep: { - l: null, - r: null - } - }; - var dx = s2.x - s1.x, dy = s2.y - s1.y, adx = dx > 0 ? dx : -dx, ady = dy > 0 ? dy : -dy; - newEdge.c = s1.x * dx + s1.y * dy + (dx * dx + dy * dy) * .5; - if (adx > ady) { - newEdge.a = 1; - newEdge.b = dy / dx; - newEdge.c /= dx; - } else { - newEdge.b = 1; - newEdge.a = dx / dy; - newEdge.c /= dy; - } - return newEdge; - }, - intersect: function(el1, el2) { - var e1 = el1.edge, e2 = el2.edge; - if (!e1 || !e2 || e1.region.r == e2.region.r) { - return null; - } - var d = e1.a * e2.b - e1.b * e2.a; - if (Math.abs(d) < 1e-10) { - return null; - } - var xint = (e1.c * e2.b - e2.c * e1.b) / d, yint = (e2.c * e1.a - e1.c * e2.a) / d, e1r = e1.region.r, e2r = e2.region.r, el, e; - if (e1r.y < e2r.y || e1r.y == e2r.y && e1r.x < e2r.x) { - el = el1; - e = e1; - } else { - el = el2; - e = e2; - } - var rightOfSite = xint >= e.region.r.x; - if (rightOfSite && el.side === "l" || !rightOfSite && el.side === "r") { - return null; - } - return { - x: xint, - y: yint - }; - }, - rightOf: function(he, p) { - var e = he.edge, topsite = e.region.r, rightOfSite = p.x > topsite.x; - if (rightOfSite && he.side === "l") { - return 1; - } - if (!rightOfSite && he.side === "r") { - return 0; - } - if (e.a === 1) { - var dyp = p.y - topsite.y, dxp = p.x - topsite.x, fast = 0, above = 0; - if (!rightOfSite && e.b < 0 || rightOfSite && e.b >= 0) { - above = fast = dyp >= e.b * dxp; - } else { - above = p.x + p.y * e.b > e.c; - if (e.b < 0) { - above = !above; - } - if (!above) { - fast = 1; - } - } - if (!fast) { - var dxs = topsite.x - e.region.l.x; - above = e.b * (dxp * dxp - dyp * dyp) < dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b); - if (e.b < 0) { - above = !above; - } - } - } else { - var yl = e.c - e.a * p.x, t1 = p.y - yl, t2 = p.x - topsite.x, t3 = yl - topsite.y; - above = t1 * t1 > t2 * t2 + t3 * t3; - } - return he.side === "l" ? above : !above; - }, - endPoint: function(edge, side, site) { - edge.ep[side] = site; - if (!edge.ep[d3_voronoi_opposite[side]]) return; - callback(edge); - }, - distance: function(s, t) { - var dx = s.x - t.x, dy = s.y - t.y; - return Math.sqrt(dx * dx + dy * dy); - } - }; - var EventQueue = { - list: [], - insert: function(he, site, offset) { - he.vertex = site; - he.ystar = site.y + offset; - for (var i = 0, list = EventQueue.list, l = list.length; i < l; i++) { - var next = list[i]; - if (he.ystar > next.ystar || he.ystar == next.ystar && site.x > next.vertex.x) { - continue; - } else { - break; - } - } - list.splice(i, 0, he); - }, - del: function(he) { - for (var i = 0, ls = EventQueue.list, l = ls.length; i < l && ls[i] != he; ++i) {} - ls.splice(i, 1); - }, - empty: function() { - return EventQueue.list.length === 0; - }, - nextEvent: function(he) { - for (var i = 0, ls = EventQueue.list, l = ls.length; i < l; ++i) { - if (ls[i] == he) return ls[i + 1]; - } - return null; - }, - min: function() { - var elem = EventQueue.list[0]; - return { - x: elem.vertex.x, - y: elem.ystar - }; - }, - extractMin: function() { - return EventQueue.list.shift(); - } - }; - EdgeList.init(); - Sites.bottomSite = Sites.list.shift(); - var newSite = Sites.list.shift(), newIntStar; - var lbnd, rbnd, llbnd, rrbnd, bisector; - var bot, top, temp, p, v; - var e, pm; - while (true) { - if (!EventQueue.empty()) { - newIntStar = EventQueue.min(); - } - if (newSite && (EventQueue.empty() || newSite.y < newIntStar.y || newSite.y == newIntStar.y && newSite.x < newIntStar.x)) { - lbnd = EdgeList.leftBound(newSite); - rbnd = EdgeList.right(lbnd); - bot = EdgeList.rightRegion(lbnd); - e = Geom.bisect(bot, newSite); - bisector = EdgeList.createHalfEdge(e, "l"); - EdgeList.insert(lbnd, bisector); - p = Geom.intersect(lbnd, bisector); - if (p) { - EventQueue.del(lbnd); - EventQueue.insert(lbnd, p, Geom.distance(p, newSite)); - } - lbnd = bisector; - bisector = EdgeList.createHalfEdge(e, "r"); - EdgeList.insert(lbnd, bisector); - p = Geom.intersect(bisector, rbnd); - if (p) { - EventQueue.insert(bisector, p, Geom.distance(p, newSite)); - } - newSite = Sites.list.shift(); - } else if (!EventQueue.empty()) { - lbnd = EventQueue.extractMin(); - llbnd = EdgeList.left(lbnd); - rbnd = EdgeList.right(lbnd); - rrbnd = EdgeList.right(rbnd); - bot = EdgeList.leftRegion(lbnd); - top = EdgeList.rightRegion(rbnd); - v = lbnd.vertex; - Geom.endPoint(lbnd.edge, lbnd.side, v); - Geom.endPoint(rbnd.edge, rbnd.side, v); - EdgeList.del(lbnd); - EventQueue.del(rbnd); - EdgeList.del(rbnd); - pm = "l"; - if (bot.y > top.y) { - temp = bot; - bot = top; - top = temp; - pm = "r"; - } - e = Geom.bisect(bot, top); - bisector = EdgeList.createHalfEdge(e, pm); - EdgeList.insert(llbnd, bisector); - Geom.endPoint(e, d3_voronoi_opposite[pm], v); - p = Geom.intersect(llbnd, bisector); - if (p) { - EventQueue.del(llbnd); - EventQueue.insert(llbnd, p, Geom.distance(p, bot)); - } - p = Geom.intersect(bisector, rrbnd); - if (p) { - EventQueue.insert(bisector, p, Geom.distance(p, bot)); - } - } else { - break; - } - } - for (lbnd = EdgeList.right(EdgeList.leftEnd); lbnd != EdgeList.rightEnd; lbnd = EdgeList.right(lbnd)) { - callback(lbnd.edge); - } - } - d3.geom.delaunay = function(vertices) { - var edges = vertices.map(function() { - return []; - }), triangles = []; - d3_voronoi_tessellate(vertices, function(e) { - edges[e.region.l.index].push(vertices[e.region.r.index]); - }); - edges.forEach(function(edge, i) { - var v = vertices[i], cx = v[0], cy = v[1]; - edge.forEach(function(v) { - v.angle = Math.atan2(v[0] - cx, v[1] - cy); - }); - edge.sort(function(a, b) { - return a.angle - b.angle; - }); - for (var j = 0, m = edge.length - 1; j < m; j++) { - triangles.push([ v, edge[j], edge[j + 1] ]); - } - }); - return triangles; - }; - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var p, i = -1, n = points.length; - if (arguments.length < 5) { - if (arguments.length === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } else { - x1 = y1 = Infinity; - x2 = y2 = -Infinity; - while (++i < n) { - p = points[i]; - if (p.x < x1) x1 = p.x; - if (p.y < y1) y1 = p.y; - if (p.x > x2) x2 = p.x; - if (p.y > y2) y2 = p.y; - } - } - } - var dx = x2 - x1, dy = y2 - y1; - if (dx > dy) y2 = y1 + dx; else x2 = x1 + dy; - function insert(n, p, x1, y1, x2, y2) { - if (isNaN(p.x) || isNaN(p.y)) return; - if (n.leaf) { - var v = n.point; - if (v) { - if (Math.abs(v.x - p.x) + Math.abs(v.y - p.y) < .01) { - insertChild(n, p, x1, y1, x2, y2); - } else { - n.point = null; - insertChild(n, v, x1, y1, x2, y2); - insertChild(n, p, x1, y1, x2, y2); - } - } else { - n.point = p; - } - } else { - insertChild(n, p, x1, y1, x2, y2); - } - } - function insertChild(n, p, x1, y1, x2, y2) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = p.x >= sx, bottom = p.y >= sy, i = (bottom << 1) + right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = sx; else x2 = sx; - if (bottom) y1 = sy; else y2 = sy; - insert(n, p, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(p) { - insert(root, p, x1, y1, x2, y2); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1, y1, x2, y2); - }; - points.forEach(root.add); - return root; - }; - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null - }; - } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - d3.time = {}; - var d3_time = Date, d3_time_daySymbols = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; - function d3_time_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_time_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - var d3_time_formatDateTime = "%a %b %e %X %Y", d3_time_formatDate = "%m/%d/%Y", d3_time_formatTime = "%H:%M:%S"; - var d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; - d3.time.format = function(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.substring(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.substring(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0 - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var date = new d3_time(); - date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H, d.M, d.S, d.L); - return date; - }; - format.toString = function() { - return template; - }; - return format; - }; - function d3_time_parse(date, template, string, j) { - var c, p, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - p = d3_time_parsers[template.charAt(i++)]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_formatPad(value, fill, width) { - value += ""; - var length = value.length; - return length < width ? new Array(width - length + 1).join(fill) + value : value; - } - var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations); - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }; - var d3_time_formats = { - a: function(d) { - return d3_time_dayAbbreviations[d.getDay()]; - }, - A: function(d) { - return d3_time_days[d.getDay()]; - }, - b: function(d) { - return d3_time_monthAbbreviations[d.getMonth()]; - }, - B: function(d) { - return d3_time_months[d.getMonth()]; - }, - c: d3.time.format(d3_time_formatDateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3.time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return d.getHours() >= 12 ? "PM" : "AM"; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3.time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3.time.mondayOfYear(d), p, 2); - }, - x: d3.time.format(d3_time_formatDate), - X: d3.time.format(d3_time_formatTime), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.substring(i)); - return n ? i += n[0].length : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.substring(i)); - return n ? i += n[0].length : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i += n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 4)); - return n ? (date.y = +n[0], i += n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i += n[0].length) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.m = n[0] - 1, i += n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.d = +n[0], i += n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.H = +n[0], i += n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.M = +n[0], i += n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.S = +n[0], i += n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.L = +n[0], i += n[0].length) : -1; - } - var d3_time_numberRe = /^\s*\d+/; - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_amPmLookup.get(string.substring(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - var d3_time_amPmLookup = d3.map({ - am: 0, - pm: 1 - }); - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - d3.time.format.utc = function(template) { - var local = d3.time.format(template); - function format(date) { - try { - d3_time = d3_time_utc; - var utc = new d3_time(); - utc._ = date; - return local(utc); - } finally { - d3_time = Date; - } - } - format.parse = function(string) { - try { - d3_time = d3_time_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_time = Date; - } - }; - format.toString = local.toString; - return format; - }; - var d3_time_formatIso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3.time.format.iso = Date.prototype.toISOString ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_time(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_time(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_time = d3_time_utc; - var utc = new d3_time_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_time = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_time = d3_time_utc; - var utc = new d3_time_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_time = Date; - } - }; - } - d3.time.second = d3_time_interval(function(date) { - return new d3_time(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3.time.seconds = d3.time.second.range; - d3.time.seconds.utc = d3.time.second.utc.range; - d3.time.minute = d3_time_interval(function(date) { - return new d3_time(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3.time.minutes = d3.time.minute.range; - d3.time.minutes.utc = d3.time.minute.utc.range; - d3.time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_time((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3.time.hours = d3.time.hour.range; - d3.time.hours.utc = d3.time.hour.utc.range; - d3.time.day = d3_time_interval(function(date) { - var day = new d3_time(1970, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3.time.days = d3.time.day.range; - d3.time.days.utc = d3.time.day.utc.range; - d3.time.dayOfYear = function(date) { - var year = d3.time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - d3_time_daySymbols.forEach(function(day, i) { - day = day.toLowerCase(); - i = 7 - i; - var interval = d3.time[day] = d3_time_interval(function(date) { - (date = d3.time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3.time.year(date).getDay(); - return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3.time[day + "s"] = interval.range; - d3.time[day + "s"].utc = interval.utc.range; - d3.time[day + "OfYear"] = function(date) { - var day = d3.time.year(date).getDay(); - return Math.floor((d3.time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3.time.week = d3.time.sunday; - d3.time.weeks = d3.time.sunday.range; - d3.time.weeks.utc = d3.time.sunday.utc.range; - d3.time.weekOfYear = d3.time.sundayOfYear; - d3.time.month = d3_time_interval(function(date) { - date = d3.time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3.time.months = d3.time.month.range; - d3.time.months.utc = d3.time.month.utc.range; - d3.time.year = d3_time_interval(function(date) { - date = d3.time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3.time.years = d3.time.year.range; - d3.time.years.utc = d3.time.year.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); - } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - scale.nice = function(m) { - return scale.domain(d3_scale_nice(scale.domain(), function() { - return m; - })); - }; - scale.ticks = function(m, k) { - var extent = d3_time_scaleExtent(scale.domain()); - if (typeof m !== "function") { - var span = extent[1] - extent[0], target = span / m, i = d3.bisect(d3_time_scaleSteps, target); - if (i == d3_time_scaleSteps.length) return methods.year(extent, m); - if (!i) return linear.ticks(m).map(d3_time_scaleDate); - if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i; - m = methods[i]; - k = m[1]; - m = m[0].range; - } - return m(extent[0], new Date(+extent[1] + 1), k); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_time_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_time_scaleDate(t) { - return new Date(t); - } - function d3_time_scaleFormat(formats) { - return function(date) { - var i = formats.length - 1, f = formats[i]; - while (!f[1](date)) f = formats[--i]; - return f[0](date); - }; - } - function d3_time_scaleSetYear(y) { - var d = new Date(y, 0, 1); - d.setFullYear(y); - return d; - } - function d3_time_scaleGetYear(d) { - var y = d.getFullYear(), d0 = d3_time_scaleSetYear(y), d1 = d3_time_scaleSetYear(y + 1); - return y + (d - d0) / (d1 - d0); - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3.time.second, 1 ], [ d3.time.second, 5 ], [ d3.time.second, 15 ], [ d3.time.second, 30 ], [ d3.time.minute, 1 ], [ d3.time.minute, 5 ], [ d3.time.minute, 15 ], [ d3.time.minute, 30 ], [ d3.time.hour, 1 ], [ d3.time.hour, 3 ], [ d3.time.hour, 6 ], [ d3.time.hour, 12 ], [ d3.time.day, 1 ], [ d3.time.day, 2 ], [ d3.time.week, 1 ], [ d3.time.month, 1 ], [ d3.time.month, 3 ], [ d3.time.year, 1 ] ]; - var d3_time_scaleLocalFormats = [ [ d3.time.format("%Y"), d3_true ], [ d3.time.format("%B"), function(d) { - return d.getMonth(); - } ], [ d3.time.format("%b %d"), function(d) { - return d.getDate() != 1; - } ], [ d3.time.format("%a %d"), function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ d3.time.format("%I %p"), function(d) { - return d.getHours(); - } ], [ d3.time.format("%I:%M"), function(d) { - return d.getMinutes(); - } ], [ d3.time.format(":%S"), function(d) { - return d.getSeconds(); - } ], [ d3.time.format(".%L"), function(d) { - return d.getMilliseconds(); - } ] ]; - var d3_time_scaleLinear = d3.scale.linear(), d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); - d3_time_scaleLocalMethods.year = function(extent, m) { - return d3_time_scaleLinear.domain(extent.map(d3_time_scaleGetYear)).ticks(m).map(d3_time_scaleSetYear); - }; - d3.time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleUTCMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUTCFormats = [ [ d3.time.format.utc("%Y"), d3_true ], [ d3.time.format.utc("%B"), function(d) { - return d.getUTCMonth(); - } ], [ d3.time.format.utc("%b %d"), function(d) { - return d.getUTCDate() != 1; - } ], [ d3.time.format.utc("%a %d"), function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ d3.time.format.utc("%I %p"), function(d) { - return d.getUTCHours(); - } ], [ d3.time.format.utc("%I:%M"), function(d) { - return d.getUTCMinutes(); - } ], [ d3.time.format.utc(":%S"), function(d) { - return d.getUTCSeconds(); - } ], [ d3.time.format.utc(".%L"), function(d) { - return d.getUTCMilliseconds(); - } ] ]; - var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); - function d3_time_scaleUTCSetYear(y) { - var d = new Date(Date.UTC(y, 0, 1)); - d.setUTCFullYear(y); - return d; - } - function d3_time_scaleUTCGetYear(d) { - var y = d.getUTCFullYear(), d0 = d3_time_scaleUTCSetYear(y), d1 = d3_time_scaleUTCSetYear(y + 1); - return y + (d - d0) / (d1 - d0); - } - d3_time_scaleUTCMethods.year = function(extent, m) { - return d3_time_scaleLinear.domain(extent.map(d3_time_scaleUTCGetYear)).ticks(m).map(d3_time_scaleUTCSetYear); - }; - d3.time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); - }; - - module.exports = d3; -})(); diff --git a/vendor/jasmine-focused.js b/vendor/jasmine-focused.js deleted file mode 100644 index ecef34023..000000000 --- a/vendor/jasmine-focused.js +++ /dev/null @@ -1,37 +0,0 @@ -var setGlobalFocusPriority = function(priority) { - env = jasmine.getEnv(); - if (!env.focusPriority) env.focusPriority = 1; - if (priority > env.focusPriority) env.focusPriority = priority; -}; - -var fdescribe = function(description, specDefinitions, priority) { - if (!priority) priority = 1; - setGlobalFocusPriority(priority) - var suite = describe(description, specDefinitions); - suite.focusPriority = priority; - return suite; -}; - -var ffdescribe = function(description, specDefinitions) { - fdescribe(description, specDefinitions, 2); -}; - -var fffdescribe = function(description, specDefinitions) { - fdescribe(description, specDefinitions, 3); -}; - -var fit = function(description, definition, priority) { - if (!priority) priority = 1; - setGlobalFocusPriority(priority); - var spec = it(description, definition); - spec.focusPriority = priority; - return spec; -}; - -var ffit = function(description, specDefinitions) { - fit(description, specDefinitions, 2); -}; - -var fffit = function(description, specDefinitions) { - fit(description, specDefinitions, 3); -}; diff --git a/vendor/md5.js b/vendor/md5.js deleted file mode 100755 index 5cb2b3319..000000000 --- a/vendor/md5.js +++ /dev/null @@ -1,391 +0,0 @@ -/* - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * Digest Algorithm, as defined in RFC 1321. - * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for more info. - */ - -/* - * Configurable variables. You may need to tweak these to be compatible with - * the server-side, but the defaults work in most cases. - */ -var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ -var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ - -/* - * These are the functions you'll usually want to call - * They take string arguments and return either hex or base-64 encoded strings - */ -function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); } -function b64_md5(s) { return rstr2b64(rstr_md5(str2rstr_utf8(s))); } -function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); } -function hex_hmac_md5(k, d) - { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } -function b64_hmac_md5(k, d) - { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } -function any_hmac_md5(k, d, e) - { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); } - -// Modified by Nathan Sobo to integrate into Atom's module system -module.exports = { - hex_md5: hex_md5, - b64_md5: b64_md5, - any_md5: any_md5, - hex_hmac_md5: hex_hmac_md5, - rstr2hex: rstr2hex, - b64_hmac_md5: b64_hmac_md5, - rstr2b64: rstr2b64, - any_hmac_md5: any_hmac_md5 -}; - -/* - * Perform a simple self-test to see if the VM is working - */ -function md5_vm_test() -{ - return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72"; -} - -/* - * Calculate the MD5 of a raw string - */ -function rstr_md5(s) -{ - return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); -} - -/* - * Calculate the HMAC-MD5, of a key and some data (raw strings) - */ -function rstr_hmac_md5(key, data) -{ - var bkey = rstr2binl(key); - if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8); - - var ipad = Array(16), opad = Array(16); - for(var i = 0; i < 16; i++) - { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } - - var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); - return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); -} - -/* - * Convert a raw string to a hex string - */ -function rstr2hex(input) -{ - try { hexcase } catch(e) { hexcase=0; } - var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; - var output = ""; - var x; - for(var i = 0; i < input.length; i++) - { - x = input.charCodeAt(i); - output += hex_tab.charAt((x >>> 4) & 0x0F) - + hex_tab.charAt( x & 0x0F); - } - return output; -} - -/* - * Convert a raw string to a base-64 string - */ -function rstr2b64(input) -{ - try { b64pad } catch(e) { b64pad=''; } - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - var output = ""; - var len = input.length; - for(var i = 0; i < len; i += 3) - { - var triplet = (input.charCodeAt(i) << 16) - | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) - | (i + 2 < len ? input.charCodeAt(i+2) : 0); - for(var j = 0; j < 4; j++) - { - if(i * 8 + j * 6 > input.length * 8) output += b64pad; - else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); - } - } - return output; -} - -/* - * Convert a raw string to an arbitrary string encoding - */ -function rstr2any(input, encoding) -{ - var divisor = encoding.length; - var i, j, q, x, quotient; - - /* Convert to an array of 16-bit big-endian values, forming the dividend */ - var dividend = Array(Math.ceil(input.length / 2)); - for(i = 0; i < dividend.length; i++) - { - dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); - } - - /* - * Repeatedly perform a long division. The binary array forms the dividend, - * the length of the encoding is the divisor. Once computed, the quotient - * forms the dividend for the next step. All remainders are stored for later - * use. - */ - var full_length = Math.ceil(input.length * 8 / - (Math.log(encoding.length) / Math.log(2))); - var remainders = Array(full_length); - for(j = 0; j < full_length; j++) - { - quotient = Array(); - x = 0; - for(i = 0; i < dividend.length; i++) - { - x = (x << 16) + dividend[i]; - q = Math.floor(x / divisor); - x -= q * divisor; - if(quotient.length > 0 || q > 0) - quotient[quotient.length] = q; - } - remainders[j] = x; - dividend = quotient; - } - - /* Convert the remainders to the output string */ - var output = ""; - for(i = remainders.length - 1; i >= 0; i--) - output += encoding.charAt(remainders[i]); - - return output; -} - -/* - * Encode a string as utf-8. - * For efficiency, this assumes the input is valid utf-16. - */ -function str2rstr_utf8(input) -{ - var output = ""; - var i = -1; - var x, y; - - while(++i < input.length) - { - /* Decode utf-16 surrogate pairs */ - x = input.charCodeAt(i); - y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; - if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) - { - x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); - i++; - } - - /* Encode output as utf-8 */ - if(x <= 0x7F) - output += String.fromCharCode(x); - else if(x <= 0x7FF) - output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), - 0x80 | ( x & 0x3F)); - else if(x <= 0xFFFF) - output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), - 0x80 | ((x >>> 6 ) & 0x3F), - 0x80 | ( x & 0x3F)); - else if(x <= 0x1FFFFF) - output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), - 0x80 | ((x >>> 12) & 0x3F), - 0x80 | ((x >>> 6 ) & 0x3F), - 0x80 | ( x & 0x3F)); - } - return output; -} - -/* - * Encode a string as utf-16 - */ -function str2rstr_utf16le(input) -{ - var output = ""; - for(var i = 0; i < input.length; i++) - output += String.fromCharCode( input.charCodeAt(i) & 0xFF, - (input.charCodeAt(i) >>> 8) & 0xFF); - return output; -} - -function str2rstr_utf16be(input) -{ - var output = ""; - for(var i = 0; i < input.length; i++) - output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, - input.charCodeAt(i) & 0xFF); - return output; -} - -/* - * Convert a raw string to an array of little-endian words - * Characters >255 have their high-byte silently ignored. - */ -function rstr2binl(input) -{ - var output = Array(input.length >> 2); - for(var i = 0; i < output.length; i++) - output[i] = 0; - for(var i = 0; i < input.length * 8; i += 8) - output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); - return output; -} - -/* - * Convert an array of little-endian words to a string - */ -function binl2rstr(input) -{ - var output = ""; - for(var i = 0; i < input.length * 32; i += 8) - output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); - return output; -} - -/* - * Calculate the MD5 of an array of little-endian words, and a bit length. - */ -function binl_md5(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; - - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - - a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); - d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); - d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); - d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i+10], 17, -42063); - b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); - d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); - - a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); - d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); - c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); - a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); - d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); - c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); - d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); - c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); - d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); - c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); - - a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); - d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); - d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); - d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); - c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); - d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); - - a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); - d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); - d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); - d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); - d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return Array(a, b, c, d); -} - -/* - * These functions implement the four basic operations the algorithm uses. - */ -function md5_cmn(q, a, b, x, s, t) -{ - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); -} -function md5_ff(a, b, c, d, x, s, t) -{ - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); -} -function md5_gg(a, b, c, d, x, s, t) -{ - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); -} -function md5_hh(a, b, c, d, x, s, t) -{ - return md5_cmn(b ^ c ^ d, a, b, x, s, t); -} -function md5_ii(a, b, c, d, x, s, t) -{ - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} diff --git a/vendor/packages/Go.tmbundle b/vendor/packages/Go.tmbundle new file mode 160000 index 000000000..d6db06051 --- /dev/null +++ b/vendor/packages/Go.tmbundle @@ -0,0 +1 @@ +Subproject commit d6db06051b8dd8683802d57e99bab6541c08f4d7 diff --git a/vendor/packages/Mustache.tmbundle b/vendor/packages/Mustache.tmbundle new file mode 160000 index 000000000..21ed7c4a4 --- /dev/null +++ b/vendor/packages/Mustache.tmbundle @@ -0,0 +1 @@ +Subproject commit 21ed7c4a49989a9bd30da496b083fe74c1c5b699 diff --git a/vendor/pegjs.js b/vendor/pegjs.js deleted file mode 100644 index 42e67b359..000000000 --- a/vendor/pegjs.js +++ /dev/null @@ -1,4528 +0,0 @@ -/* - * PEG.js 0.7.0 - * - * http://pegjs.majda.cz/ - * - * Copyright (c) 2010-2012 David Majda - * Licensend under the MIT license. - */ -var PEG = (function(undefined) { - -var PEG = { - /* PEG.js version (uses semantic versioning). */ - VERSION: "0.7.0", - - /* - * Generates a parser from a specified grammar and returns it. - * - * The grammar must be a string in the format described by the metagramar in - * the parser.pegjs file. - * - * Throws |PEG.parser.SyntaxError| if the grammar contains a syntax error or - * |PEG.GrammarError| if it contains a semantic error. Note that not all - * errors are detected during the generation and some may protrude to the - * generated parser and cause its malfunction. - */ - buildParser: function(grammar, options) { - return PEG.compiler.compile(PEG.parser.parse(grammar), options); - } -}; - -/* Thrown when the grammar contains an error. */ - -PEG.GrammarError = function(message) { - this.name = "PEG.GrammarError"; - this.message = message; -}; - -PEG.GrammarError.prototype = Error.prototype; - -/* Like Python's |range|, but without |step|. */ -function range(start, stop) { - if (stop === undefined) { - stop = start; - start = 0; - } - - var result = new Array(Math.max(0, stop - start)); - for (var i = 0, j = start; j < stop; i++, j++) { - result[i] = j; - } - return result; -} - -function find(array, callback) { - var length = array.length; - for (var i = 0; i < length; i++) { - if (callback(array[i])) { - return array[i]; - } - } -} - -function contains(array, value) { - /* - * Stupid IE does not have Array.prototype.indexOf, otherwise this function - * would be a one-liner. - */ - var length = array.length; - for (var i = 0; i < length; i++) { - if (array[i] === value) { - return true; - } - } - return false; -} - -function each(array, callback) { - var length = array.length; - for (var i = 0; i < length; i++) { - callback(array[i], i); - } -} - -function map(array, callback) { - var result = []; - var length = array.length; - for (var i = 0; i < length; i++) { - result[i] = callback(array[i], i); - } - return result; -} - -function pluck(array, key) { - return map(array, function (e) { return e[key]; }); -} - -function keys(object) { - var result = []; - for (var key in object) { - result.push(key); - } - return result; -} - -function values(object) { - var result = []; - for (var key in object) { - result.push(object[key]); - } - return result; -} - -/* - * Returns a string padded on the left to a desired length with a character. - * - * The code needs to be in sync with the code template in the compilation - * function for "action" nodes. - */ -function padLeft(input, padding, length) { - var result = input; - - var padLength = length - input.length; - for (var i = 0; i < padLength; i++) { - result = padding + result; - } - - return result; -} - -/* - * Returns an escape sequence for given character. Uses \x for characters <= - * 0xFF to save space, \u for the rest. - * - * The code needs to be in sync with the code template in the compilation - * function for "action" nodes. - */ -function escape(ch) { - var charCode = ch.charCodeAt(0); - var escapeChar; - var length; - - if (charCode <= 0xFF) { - escapeChar = 'x'; - length = 2; - } else { - escapeChar = 'u'; - length = 4; - } - - return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); -} - -/* - * Surrounds the string with quotes and escapes characters inside so that the - * result is a valid JavaScript string. - * - * The code needs to be in sync with the code template in the compilation - * function for "action" nodes. - */ -function quote(s) { - /* - * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string - * literal except for the closing quote character, backslash, carriage return, - * line separator, paragraph separator, and line feed. Any character may - * appear in the form of an escape sequence. - * - * For portability, we also escape escape all control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used because - * JSHint does not like the first and IE the second. - */ - return '"' + s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing quote character - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) - + '"'; -} - -/* - * Escapes characters inside the string so that it can be used as a list of - * characters in a character class of a regular expression. - */ -function quoteForRegexpClass(s) { - /* - * Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1. - * - * For portability, we also escape escape all control and non-ASCII - * characters. - */ - return s - .replace(/\\/g, '\\\\') // backslash - .replace(/\//g, '\\/') // closing slash - .replace(/\]/g, '\\]') // closing bracket - .replace(/-/g, '\\-') // dash - .replace(/\0/g, '\\0') // null - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\v/g, '\\x0B') // vertical tab - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x01-\x08\x0E-\x1F\x80-\uFFFF]/g, escape); -} - -/* - * Builds a node visitor -- a function which takes a node and any number of - * other parameters, calls an appropriate function according to the node type, - * passes it all its parameters and returns its value. The functions for various - * node types are passed in a parameter to |buildNodeVisitor| as a hash. - */ -function buildNodeVisitor(functions) { - return function(node) { - return functions[node.type].apply(null, arguments); - }; -} - -function findRuleByName(ast, name) { - return find(ast.rules, function(r) { return r.name === name; }); -} -PEG.parser = (function(){ - /* - * Generated by PEG.js 0.7.0. - * - * http://pegjs.majda.cz/ - */ - - function quote(s) { - /* - * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a - * string literal except for the closing quote character, backslash, - * carriage return, line separator, paragraph separator, and line feed. - * Any character may appear in the form of an escape sequence. - * - * For portability, we also escape escape all control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used - * because JSHint does not like the first and IE the second. - */ - return '"' + s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing quote character - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) - + '"'; - } - - var result = { - /* - * Parses the input with a generated parser. If the parsing is successfull, - * returns a value explicitly or implicitly specified by the grammar from - * which the parser was generated (see |PEG.buildParser|). If the parsing is - * unsuccessful, throws |PEG.parser.SyntaxError| describing the error. - */ - parse: function(input, startRule) { - var parseFunctions = { - "grammar": parse_grammar, - "initializer": parse_initializer, - "rule": parse_rule, - "choice": parse_choice, - "sequence": parse_sequence, - "labeled": parse_labeled, - "prefixed": parse_prefixed, - "suffixed": parse_suffixed, - "primary": parse_primary, - "action": parse_action, - "braced": parse_braced, - "nonBraceCharacters": parse_nonBraceCharacters, - "nonBraceCharacter": parse_nonBraceCharacter, - "equals": parse_equals, - "colon": parse_colon, - "semicolon": parse_semicolon, - "slash": parse_slash, - "and": parse_and, - "not": parse_not, - "question": parse_question, - "star": parse_star, - "plus": parse_plus, - "lparen": parse_lparen, - "rparen": parse_rparen, - "dot": parse_dot, - "identifier": parse_identifier, - "literal": parse_literal, - "string": parse_string, - "doubleQuotedString": parse_doubleQuotedString, - "doubleQuotedCharacter": parse_doubleQuotedCharacter, - "simpleDoubleQuotedCharacter": parse_simpleDoubleQuotedCharacter, - "singleQuotedString": parse_singleQuotedString, - "singleQuotedCharacter": parse_singleQuotedCharacter, - "simpleSingleQuotedCharacter": parse_simpleSingleQuotedCharacter, - "class": parse_class, - "classCharacterRange": parse_classCharacterRange, - "classCharacter": parse_classCharacter, - "bracketDelimitedCharacter": parse_bracketDelimitedCharacter, - "simpleBracketDelimitedCharacter": parse_simpleBracketDelimitedCharacter, - "simpleEscapeSequence": parse_simpleEscapeSequence, - "zeroEscapeSequence": parse_zeroEscapeSequence, - "hexEscapeSequence": parse_hexEscapeSequence, - "unicodeEscapeSequence": parse_unicodeEscapeSequence, - "eolEscapeSequence": parse_eolEscapeSequence, - "digit": parse_digit, - "hexDigit": parse_hexDigit, - "letter": parse_letter, - "lowerCaseLetter": parse_lowerCaseLetter, - "upperCaseLetter": parse_upperCaseLetter, - "__": parse___, - "comment": parse_comment, - "singleLineComment": parse_singleLineComment, - "multiLineComment": parse_multiLineComment, - "eol": parse_eol, - "eolChar": parse_eolChar, - "whitespace": parse_whitespace - }; - - if (startRule !== undefined) { - if (parseFunctions[startRule] === undefined) { - throw new Error("Invalid rule name: " + quote(startRule) + "."); - } - } else { - startRule = "grammar"; - } - - var pos = 0; - var reportFailures = 0; - var rightmostFailuresPos = 0; - var rightmostFailuresExpected = []; - - function padLeft(input, padding, length) { - var result = input; - - var padLength = length - input.length; - for (var i = 0; i < padLength; i++) { - result = padding + result; - } - - return result; - } - - function escape(ch) { - var charCode = ch.charCodeAt(0); - var escapeChar; - var length; - - if (charCode <= 0xFF) { - escapeChar = 'x'; - length = 2; - } else { - escapeChar = 'u'; - length = 4; - } - - return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); - } - - function matchFailed(failure) { - if (pos < rightmostFailuresPos) { - return; - } - - if (pos > rightmostFailuresPos) { - rightmostFailuresPos = pos; - rightmostFailuresExpected = []; - } - - rightmostFailuresExpected.push(failure); - } - - function parse_grammar() { - var result0, result1, result2, result3; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse___(); - if (result0 !== null) { - result1 = parse_initializer(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result3 = parse_rule(); - if (result3 !== null) { - result2 = []; - while (result3 !== null) { - result2.push(result3); - result3 = parse_rule(); - } - } else { - result2 = null; - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, initializer, rules) { - return { - type: "grammar", - initializer: initializer !== "" ? initializer : null, - rules: rules, - startRule: rules[0].name - }; - })(pos0, result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_initializer() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_action(); - if (result0 !== null) { - result1 = parse_semicolon(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, code) { - return { - type: "initializer", - code: code - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_rule() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_identifier(); - if (result0 !== null) { - result1 = parse_string(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = parse_equals(); - if (result2 !== null) { - result3 = parse_choice(); - if (result3 !== null) { - result4 = parse_semicolon(); - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name, displayName, expression) { - return { - type: "rule", - name: name, - displayName: displayName !== "" ? displayName : null, - expression: expression - }; - })(pos0, result0[0], result0[1], result0[3]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_choice() { - var result0, result1, result2, result3; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - result0 = parse_sequence(); - if (result0 !== null) { - result1 = []; - pos2 = pos; - result2 = parse_slash(); - if (result2 !== null) { - result3 = parse_sequence(); - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - while (result2 !== null) { - result1.push(result2); - pos2 = pos; - result2 = parse_slash(); - if (result2 !== null) { - result3 = parse_sequence(); - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos2; - } - } else { - result2 = null; - pos = pos2; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - if (tail.length > 0) { - var alternatives = [head].concat(map( - tail, - function(element) { return element[1]; } - )); - return { - type: "choice", - alternatives: alternatives - }; - } else { - return head; - } - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_sequence() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = []; - result1 = parse_labeled(); - while (result1 !== null) { - result0.push(result1); - result1 = parse_labeled(); - } - if (result0 !== null) { - result1 = parse_action(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, elements, code) { - var expression = elements.length !== 1 - ? { - type: "sequence", - elements: elements - } - : elements[0]; - return { - type: "action", - expression: expression, - code: code - }; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - result0 = []; - result1 = parse_labeled(); - while (result1 !== null) { - result0.push(result1); - result1 = parse_labeled(); - } - if (result0 !== null) { - result0 = (function(offset, elements) { - return elements.length !== 1 - ? { - type: "sequence", - elements: elements - } - : elements[0]; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - } - return result0; - } - - function parse_labeled() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_identifier(); - if (result0 !== null) { - result1 = parse_colon(); - if (result1 !== null) { - result2 = parse_prefixed(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, label, expression) { - return { - type: "labeled", - label: label, - expression: expression - }; - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_prefixed(); - } - return result0; - } - - function parse_prefixed() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_and(); - if (result0 !== null) { - result1 = parse_action(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, code) { - return { - type: "semantic_and", - code: code - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_and(); - if (result0 !== null) { - result1 = parse_suffixed(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "simple_and", - expression: expression - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_not(); - if (result0 !== null) { - result1 = parse_action(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, code) { - return { - type: "semantic_not", - code: code - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_not(); - if (result0 !== null) { - result1 = parse_suffixed(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "simple_not", - expression: expression - }; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_suffixed(); - } - } - } - } - return result0; - } - - function parse_suffixed() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = parse_question(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "optional", - expression: expression - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = parse_star(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "zero_or_more", - expression: expression - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_primary(); - if (result0 !== null) { - result1 = parse_plus(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { - return { - type: "one_or_more", - expression: expression - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_primary(); - } - } - } - return result0; - } - - function parse_primary() { - var result0, result1, result2; - var pos0, pos1, pos2, pos3; - - pos0 = pos; - pos1 = pos; - result0 = parse_identifier(); - if (result0 !== null) { - pos2 = pos; - reportFailures++; - pos3 = pos; - result1 = parse_string(); - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = parse_equals(); - if (result2 !== null) { - result1 = [result1, result2]; - } else { - result1 = null; - pos = pos3; - } - } else { - result1 = null; - pos = pos3; - } - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, name) { - return { - type: "rule_ref", - name: name - }; - })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_literal(); - if (result0 === null) { - pos0 = pos; - result0 = parse_dot(); - if (result0 !== null) { - result0 = (function(offset) { return { type: "any" }; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - if (result0 === null) { - result0 = parse_class(); - if (result0 === null) { - pos0 = pos; - pos1 = pos; - result0 = parse_lparen(); - if (result0 !== null) { - result1 = parse_choice(); - if (result1 !== null) { - result2 = parse_rparen(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, expression) { return expression; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - } - } - } - } - return result0; - } - - function parse_action() { - var result0, result1; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_braced(); - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, braced) { return braced.substr(1, braced.length - 2); })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("action"); - } - return result0; - } - - function parse_braced() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 123) { - result0 = "{"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"{\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_braced(); - if (result2 === null) { - result2 = parse_nonBraceCharacter(); - } - while (result2 !== null) { - result1.push(result2); - result2 = parse_braced(); - if (result2 === null) { - result2 = parse_nonBraceCharacter(); - } - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 125) { - result2 = "}"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"}\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, parts) { - return "{" + parts.join("") + "}"; - })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_nonBraceCharacters() { - var result0, result1; - var pos0; - - pos0 = pos; - result1 = parse_nonBraceCharacter(); - if (result1 !== null) { - result0 = []; - while (result1 !== null) { - result0.push(result1); - result1 = parse_nonBraceCharacter(); - } - } else { - result0 = null; - } - if (result0 !== null) { - result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_nonBraceCharacter() { - var result0; - - if (/^[^{}]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[^{}]"); - } - } - return result0; - } - - function parse_equals() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 61) { - result0 = "="; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"=\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "="; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_colon() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 58) { - result0 = ":"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\":\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return ":"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_semicolon() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 59) { - result0 = ";"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\";\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return ";"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_slash() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 47) { - result0 = "/"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"/\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "/"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_and() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 38) { - result0 = "&"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"&\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "&"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_not() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 33) { - result0 = "!"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"!\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "!"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_question() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 63) { - result0 = "?"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"?\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "?"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_star() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 42) { - result0 = "*"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"*\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "*"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_plus() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 43) { - result0 = "+"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"+\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "+"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_lparen() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 40) { - result0 = "("; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"(\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "("; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_rparen() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 41) { - result0 = ")"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\")\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return ")"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_dot() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 46) { - result0 = "."; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\".\""); - } - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "."; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_identifier() { - var result0, result1, result2; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_letter(); - if (result0 === null) { - if (input.charCodeAt(pos) === 95) { - result0 = "_"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"_\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 36) { - result0 = "$"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_letter(); - if (result2 === null) { - result2 = parse_digit(); - if (result2 === null) { - if (input.charCodeAt(pos) === 95) { - result2 = "_"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"_\""); - } - } - if (result2 === null) { - if (input.charCodeAt(pos) === 36) { - result2 = "$"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - } - } - } - while (result2 !== null) { - result1.push(result2); - result2 = parse_letter(); - if (result2 === null) { - result2 = parse_digit(); - if (result2 === null) { - if (input.charCodeAt(pos) === 95) { - result2 = "_"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"_\""); - } - } - if (result2 === null) { - if (input.charCodeAt(pos) === 36) { - result2 = "$"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"$\""); - } - } - } - } - } - } - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, head, tail) { - return head + tail.join(""); - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("identifier"); - } - return result0; - } - - function parse_literal() { - var result0, result1, result2; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_doubleQuotedString(); - if (result0 === null) { - result0 = parse_singleQuotedString(); - } - if (result0 !== null) { - if (input.charCodeAt(pos) === 105) { - result1 = "i"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"i\""); - } - } - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = parse___(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, value, flags) { - return { - type: "literal", - value: value, - ignoreCase: flags === "i" - }; - })(pos0, result0[0], result0[1]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("literal"); - } - return result0; - } - - function parse_string() { - var result0, result1; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - result0 = parse_doubleQuotedString(); - if (result0 === null) { - result0 = parse_singleQuotedString(); - } - if (result0 !== null) { - result1 = parse___(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, string) { return string; })(pos0, result0[0]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("string"); - } - return result0; - } - - function parse_doubleQuotedString() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 34) { - result0 = "\""; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_doubleQuotedCharacter(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_doubleQuotedCharacter(); - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 34) { - result2 = "\""; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_doubleQuotedCharacter() { - var result0; - - result0 = parse_simpleDoubleQuotedCharacter(); - if (result0 === null) { - result0 = parse_simpleEscapeSequence(); - if (result0 === null) { - result0 = parse_zeroEscapeSequence(); - if (result0 === null) { - result0 = parse_hexEscapeSequence(); - if (result0 === null) { - result0 = parse_unicodeEscapeSequence(); - if (result0 === null) { - result0 = parse_eolEscapeSequence(); - } - } - } - } - } - return result0; - } - - function parse_simpleDoubleQuotedCharacter() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 34) { - result0 = "\""; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\"\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 === null) { - result0 = parse_eolChar(); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos2; - } - if (result0 !== null) { - if (input.length > pos) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { return char_; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_singleQuotedString() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 39) { - result0 = "'"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result0 !== null) { - result1 = []; - result2 = parse_singleQuotedCharacter(); - while (result2 !== null) { - result1.push(result2); - result2 = parse_singleQuotedCharacter(); - } - if (result1 !== null) { - if (input.charCodeAt(pos) === 39) { - result2 = "'"; - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_singleQuotedCharacter() { - var result0; - - result0 = parse_simpleSingleQuotedCharacter(); - if (result0 === null) { - result0 = parse_simpleEscapeSequence(); - if (result0 === null) { - result0 = parse_zeroEscapeSequence(); - if (result0 === null) { - result0 = parse_hexEscapeSequence(); - if (result0 === null) { - result0 = parse_unicodeEscapeSequence(); - if (result0 === null) { - result0 = parse_eolEscapeSequence(); - } - } - } - } - } - return result0; - } - - function parse_simpleSingleQuotedCharacter() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 39) { - result0 = "'"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"'\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 === null) { - result0 = parse_eolChar(); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos2; - } - if (result0 !== null) { - if (input.length > pos) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { return char_; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_class() { - var result0, result1, result2, result3, result4, result5; - var pos0, pos1; - - reportFailures++; - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 91) { - result0 = "["; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"[\""); - } - } - if (result0 !== null) { - if (input.charCodeAt(pos) === 94) { - result1 = "^"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"^\""); - } - } - result1 = result1 !== null ? result1 : ""; - if (result1 !== null) { - result2 = []; - result3 = parse_classCharacterRange(); - if (result3 === null) { - result3 = parse_classCharacter(); - } - while (result3 !== null) { - result2.push(result3); - result3 = parse_classCharacterRange(); - if (result3 === null) { - result3 = parse_classCharacter(); - } - } - if (result2 !== null) { - if (input.charCodeAt(pos) === 93) { - result3 = "]"; - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("\"]\""); - } - } - if (result3 !== null) { - if (input.charCodeAt(pos) === 105) { - result4 = "i"; - pos++; - } else { - result4 = null; - if (reportFailures === 0) { - matchFailed("\"i\""); - } - } - result4 = result4 !== null ? result4 : ""; - if (result4 !== null) { - result5 = parse___(); - if (result5 !== null) { - result0 = [result0, result1, result2, result3, result4, result5]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, inverted, parts, flags) { - var partsConverted = map(parts, function(part) { return part.data; }); - var rawText = "[" - + inverted - + map(parts, function(part) { return part.rawText; }).join("") - + "]" - + flags; - - return { - type: "class", - inverted: inverted === "^", - ignoreCase: flags === "i", - parts: partsConverted, - // FIXME: Get the raw text from the input directly. - rawText: rawText - }; - })(pos0, result0[1], result0[2], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("character class"); - } - return result0; - } - - function parse_classCharacterRange() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - result0 = parse_classCharacter(); - if (result0 !== null) { - if (input.charCodeAt(pos) === 45) { - result1 = "-"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"-\""); - } - } - if (result1 !== null) { - result2 = parse_classCharacter(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, begin, end) { - if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) { - throw new this.SyntaxError( - "Invalid character range: " + begin.rawText + "-" + end.rawText + "." - ); - } - - return { - data: [begin.data, end.data], - // FIXME: Get the raw text from the input directly. - rawText: begin.rawText + "-" + end.rawText - }; - })(pos0, result0[0], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_classCharacter() { - var result0; - var pos0; - - pos0 = pos; - result0 = parse_bracketDelimitedCharacter(); - if (result0 !== null) { - result0 = (function(offset, char_) { - return { - data: char_, - // FIXME: Get the raw text from the input directly. - rawText: quoteForRegexpClass(char_) - }; - })(pos0, result0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_bracketDelimitedCharacter() { - var result0; - - result0 = parse_simpleBracketDelimitedCharacter(); - if (result0 === null) { - result0 = parse_simpleEscapeSequence(); - if (result0 === null) { - result0 = parse_zeroEscapeSequence(); - if (result0 === null) { - result0 = parse_hexEscapeSequence(); - if (result0 === null) { - result0 = parse_unicodeEscapeSequence(); - if (result0 === null) { - result0 = parse_eolEscapeSequence(); - } - } - } - } - } - return result0; - } - - function parse_simpleBracketDelimitedCharacter() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.charCodeAt(pos) === 93) { - result0 = "]"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"]\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 === null) { - result0 = parse_eolChar(); - } - } - reportFailures--; - if (result0 === null) { - result0 = ""; - } else { - result0 = null; - pos = pos2; - } - if (result0 !== null) { - if (input.length > pos) { - result1 = input.charAt(pos); - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { return char_; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_simpleEscapeSequence() { - var result0, result1, result2; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_digit(); - if (result1 === null) { - if (input.charCodeAt(pos) === 120) { - result1 = "x"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"x\""); - } - } - if (result1 === null) { - if (input.charCodeAt(pos) === 117) { - result1 = "u"; - pos++; - } else { - result1 = null; - if (reportFailures === 0) { - matchFailed("\"u\""); - } - } - if (result1 === null) { - result1 = parse_eolChar(); - } - } - } - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - if (input.length > pos) { - result2 = input.charAt(pos); - pos++; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, char_) { - return char_ - .replace("b", "\b") - .replace("f", "\f") - .replace("n", "\n") - .replace("r", "\r") - .replace("t", "\t") - .replace("v", "\x0B"); // IE does not recognize "\v". - })(pos0, result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_zeroEscapeSequence() { - var result0, result1; - var pos0, pos1, pos2; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\0") { - result0 = "\\0"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\0\""); - } - } - if (result0 !== null) { - pos2 = pos; - reportFailures++; - result1 = parse_digit(); - reportFailures--; - if (result1 === null) { - result1 = ""; - } else { - result1 = null; - pos = pos2; - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset) { return "\x00"; })(pos0); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_hexEscapeSequence() { - var result0, result1, result2; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\x") { - result0 = "\\x"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\x\""); - } - } - if (result0 !== null) { - result1 = parse_hexDigit(); - if (result1 !== null) { - result2 = parse_hexDigit(); - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, h1, h2) { - return String.fromCharCode(parseInt(h1 + h2, 16)); - })(pos0, result0[1], result0[2]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_unicodeEscapeSequence() { - var result0, result1, result2, result3, result4; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.substr(pos, 2) === "\\u") { - result0 = "\\u"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\u\""); - } - } - if (result0 !== null) { - result1 = parse_hexDigit(); - if (result1 !== null) { - result2 = parse_hexDigit(); - if (result2 !== null) { - result3 = parse_hexDigit(); - if (result3 !== null) { - result4 = parse_hexDigit(); - if (result4 !== null) { - result0 = [result0, result1, result2, result3, result4]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, h1, h2, h3, h4) { - return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16)); - })(pos0, result0[1], result0[2], result0[3], result0[4]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_eolEscapeSequence() { - var result0, result1; - var pos0, pos1; - - pos0 = pos; - pos1 = pos; - if (input.charCodeAt(pos) === 92) { - result0 = "\\"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\\\\""); - } - } - if (result0 !== null) { - result1 = parse_eol(); - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos1; - } - } else { - result0 = null; - pos = pos1; - } - if (result0 !== null) { - result0 = (function(offset, eol) { return eol; })(pos0, result0[1]); - } - if (result0 === null) { - pos = pos0; - } - return result0; - } - - function parse_digit() { - var result0; - - if (/^[0-9]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[0-9]"); - } - } - return result0; - } - - function parse_hexDigit() { - var result0; - - if (/^[0-9a-fA-F]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[0-9a-fA-F]"); - } - } - return result0; - } - - function parse_letter() { - var result0; - - result0 = parse_lowerCaseLetter(); - if (result0 === null) { - result0 = parse_upperCaseLetter(); - } - return result0; - } - - function parse_lowerCaseLetter() { - var result0; - - if (/^[a-z]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[a-z]"); - } - } - return result0; - } - - function parse_upperCaseLetter() { - var result0; - - if (/^[A-Z]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[A-Z]"); - } - } - return result0; - } - - function parse___() { - var result0, result1; - - result0 = []; - result1 = parse_whitespace(); - if (result1 === null) { - result1 = parse_eol(); - if (result1 === null) { - result1 = parse_comment(); - } - } - while (result1 !== null) { - result0.push(result1); - result1 = parse_whitespace(); - if (result1 === null) { - result1 = parse_eol(); - if (result1 === null) { - result1 = parse_comment(); - } - } - } - return result0; - } - - function parse_comment() { - var result0; - - reportFailures++; - result0 = parse_singleLineComment(); - if (result0 === null) { - result0 = parse_multiLineComment(); - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("comment"); - } - return result0; - } - - function parse_singleLineComment() { - var result0, result1, result2, result3; - var pos0, pos1, pos2; - - pos0 = pos; - if (input.substr(pos, 2) === "//") { - result0 = "//"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"//\""); - } - } - if (result0 !== null) { - result1 = []; - pos1 = pos; - pos2 = pos; - reportFailures++; - result2 = parse_eolChar(); - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - while (result2 !== null) { - result1.push(result2); - pos1 = pos; - pos2 = pos; - reportFailures++; - result2 = parse_eolChar(); - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - } - if (result1 !== null) { - result0 = [result0, result1]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_multiLineComment() { - var result0, result1, result2, result3; - var pos0, pos1, pos2; - - pos0 = pos; - if (input.substr(pos, 2) === "/*") { - result0 = "/*"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"/*\""); - } - } - if (result0 !== null) { - result1 = []; - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.substr(pos, 2) === "*/") { - result2 = "*/"; - pos += 2; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"*/\""); - } - } - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - while (result2 !== null) { - result1.push(result2); - pos1 = pos; - pos2 = pos; - reportFailures++; - if (input.substr(pos, 2) === "*/") { - result2 = "*/"; - pos += 2; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"*/\""); - } - } - reportFailures--; - if (result2 === null) { - result2 = ""; - } else { - result2 = null; - pos = pos2; - } - if (result2 !== null) { - if (input.length > pos) { - result3 = input.charAt(pos); - pos++; - } else { - result3 = null; - if (reportFailures === 0) { - matchFailed("any character"); - } - } - if (result3 !== null) { - result2 = [result2, result3]; - } else { - result2 = null; - pos = pos1; - } - } else { - result2 = null; - pos = pos1; - } - } - if (result1 !== null) { - if (input.substr(pos, 2) === "*/") { - result2 = "*/"; - pos += 2; - } else { - result2 = null; - if (reportFailures === 0) { - matchFailed("\"*/\""); - } - } - if (result2 !== null) { - result0 = [result0, result1, result2]; - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - } else { - result0 = null; - pos = pos0; - } - return result0; - } - - function parse_eol() { - var result0; - - reportFailures++; - if (input.charCodeAt(pos) === 10) { - result0 = "\n"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\n\""); - } - } - if (result0 === null) { - if (input.substr(pos, 2) === "\r\n") { - result0 = "\r\n"; - pos += 2; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\r\\n\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 13) { - result0 = "\r"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\r\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 8232) { - result0 = "\u2028"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\u2028\""); - } - } - if (result0 === null) { - if (input.charCodeAt(pos) === 8233) { - result0 = "\u2029"; - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("\"\\u2029\""); - } - } - } - } - } - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("end of line"); - } - return result0; - } - - function parse_eolChar() { - var result0; - - if (/^[\n\r\u2028\u2029]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[\\n\\r\\u2028\\u2029]"); - } - } - return result0; - } - - function parse_whitespace() { - var result0; - - reportFailures++; - if (/^[ \t\x0B\f\xA0\uFEFF\u1680\u180E\u2000-\u200A\u202F\u205F\u3000]/.test(input.charAt(pos))) { - result0 = input.charAt(pos); - pos++; - } else { - result0 = null; - if (reportFailures === 0) { - matchFailed("[ \\t\\x0B\\f\\xA0\\uFEFF\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]"); - } - } - reportFailures--; - if (reportFailures === 0 && result0 === null) { - matchFailed("whitespace"); - } - return result0; - } - - - function cleanupExpected(expected) { - expected.sort(); - - var lastExpected = null; - var cleanExpected = []; - for (var i = 0; i < expected.length; i++) { - if (expected[i] !== lastExpected) { - cleanExpected.push(expected[i]); - lastExpected = expected[i]; - } - } - return cleanExpected; - } - - function computeErrorPosition() { - /* - * The first idea was to use |String.split| to break the input up to the - * error position along newlines and derive the line and column from - * there. However IE's |split| implementation is so broken that it was - * enough to prevent it. - */ - - var line = 1; - var column = 1; - var seenCR = false; - - for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) { - var ch = input.charAt(i); - if (ch === "\n") { - if (!seenCR) { line++; } - column = 1; - seenCR = false; - } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { - line++; - column = 1; - seenCR = true; - } else { - column++; - seenCR = false; - } - } - - return { line: line, column: column }; - } - - - var result = parseFunctions[startRule](); - - /* - * The parser is now in one of the following three states: - * - * 1. The parser successfully parsed the whole input. - * - * - |result !== null| - * - |pos === input.length| - * - |rightmostFailuresExpected| may or may not contain something - * - * 2. The parser successfully parsed only a part of the input. - * - * - |result !== null| - * - |pos < input.length| - * - |rightmostFailuresExpected| may or may not contain something - * - * 3. The parser did not successfully parse any part of the input. - * - * - |result === null| - * - |pos === 0| - * - |rightmostFailuresExpected| contains at least one failure - * - * All code following this comment (including called functions) must - * handle these states. - */ - if (result === null || pos !== input.length) { - var offset = Math.max(pos, rightmostFailuresPos); - var found = offset < input.length ? input.charAt(offset) : null; - var errorPosition = computeErrorPosition(); - - throw new this.SyntaxError( - cleanupExpected(rightmostFailuresExpected), - found, - offset, - errorPosition.line, - errorPosition.column - ); - } - - return result; - }, - - /* Returns the parser source code. */ - toSource: function() { return this._source; } - }; - - /* Thrown when a parser encounters a syntax error. */ - - result.SyntaxError = function(expected, found, offset, line, column) { - function buildMessage(expected, found) { - var expectedHumanized, foundHumanized; - - switch (expected.length) { - case 0: - expectedHumanized = "end of input"; - break; - case 1: - expectedHumanized = expected[0]; - break; - default: - expectedHumanized = expected.slice(0, expected.length - 1).join(", ") - + " or " - + expected[expected.length - 1]; - } - - foundHumanized = found ? quote(found) : "end of input"; - - return "Expected " + expectedHumanized + " but " + foundHumanized + " found."; - } - - this.name = "SyntaxError"; - this.expected = expected; - this.found = found; - this.message = buildMessage(expected, found); - this.offset = offset; - this.line = line; - this.column = column; - }; - - result.SyntaxError.prototype = Error.prototype; - - return result; -})(); -PEG.compiler = { - /* - * Names of passes that will get run during the compilation (in the specified - * order). - */ - appliedPassNames: [ - "reportMissingRules", - "reportLeftRecursion", - "removeProxyRules", - "computeVarNames", - "computeParams" - ], - - /* - * Generates a parser from a specified grammar AST. Throws |PEG.GrammarError| - * if the AST contains a semantic error. Note that not all errors are detected - * during the generation and some may protrude to the generated parser and - * cause its malfunction. - */ - compile: function(ast, options) { - var that = this; - - each(this.appliedPassNames, function(passName) { - that.passes[passName](ast); - }); - - var source = this.emitter(ast, options); - var result = eval(source); - result._source = source; - - return result; - } -}; - -/* - * Compiler passes. - * - * Each pass is a function that is passed the AST. It can perform checks on it - * or modify it as needed. If the pass encounters a semantic error, it throws - * |PEG.GrammarError|. - */ -PEG.compiler.passes = { - /* Checks that all referenced rules exist. */ - reportMissingRules: function(ast) { - function nop() {} - - function checkExpression(node) { check(node.expression); } - - function checkSubnodes(propertyName) { - return function(node) { each(node[propertyName], check); }; - } - - var check = buildNodeVisitor({ - grammar: checkSubnodes("rules"), - rule: checkExpression, - choice: checkSubnodes("alternatives"), - sequence: checkSubnodes("elements"), - labeled: checkExpression, - simple_and: checkExpression, - simple_not: checkExpression, - semantic_and: nop, - semantic_not: nop, - optional: checkExpression, - zero_or_more: checkExpression, - one_or_more: checkExpression, - action: checkExpression, - - rule_ref: - function(node) { - if (!findRuleByName(ast, node.name)) { - throw new PEG.GrammarError( - "Referenced rule \"" + node.name + "\" does not exist." - ); - } - }, - - literal: nop, - any: nop, - "class": nop - }); - - check(ast); - }, - - /* Checks that no left recursion is present. */ - reportLeftRecursion: function(ast) { - function nop() {} - - function checkExpression(node, appliedRules) { - check(node.expression, appliedRules); - } - - function checkSubnodes(propertyName) { - return function(node, appliedRules) { - each(node[propertyName], function(subnode) { - check(subnode, appliedRules); - }); - }; - } - - var check = buildNodeVisitor({ - grammar: checkSubnodes("rules"), - - rule: - function(node, appliedRules) { - check(node.expression, appliedRules.concat(node.name)); - }, - - choice: checkSubnodes("alternatives"), - - sequence: - function(node, appliedRules) { - if (node.elements.length > 0) { - check(node.elements[0], appliedRules); - } - }, - - labeled: checkExpression, - simple_and: checkExpression, - simple_not: checkExpression, - semantic_and: nop, - semantic_not: nop, - optional: checkExpression, - zero_or_more: checkExpression, - one_or_more: checkExpression, - action: checkExpression, - - rule_ref: - function(node, appliedRules) { - if (contains(appliedRules, node.name)) { - throw new PEG.GrammarError( - "Left recursion detected for rule \"" + node.name + "\"." - ); - } - check(findRuleByName(ast, node.name), appliedRules); - }, - - literal: nop, - any: nop, - "class": nop - }); - - check(ast, []); - }, - - /* - * Removes proxy rules -- that is, rules that only delegate to other rule. - */ - removeProxyRules: function(ast) { - function isProxyRule(node) { - return node.type === "rule" && node.expression.type === "rule_ref"; - } - - function replaceRuleRefs(ast, from, to) { - function nop() {} - - function replaceInExpression(node, from, to) { - replace(node.expression, from, to); - } - - function replaceInSubnodes(propertyName) { - return function(node, from, to) { - each(node[propertyName], function(subnode) { - replace(subnode, from, to); - }); - }; - } - - var replace = buildNodeVisitor({ - grammar: replaceInSubnodes("rules"), - rule: replaceInExpression, - choice: replaceInSubnodes("alternatives"), - sequence: replaceInSubnodes("elements"), - labeled: replaceInExpression, - simple_and: replaceInExpression, - simple_not: replaceInExpression, - semantic_and: nop, - semantic_not: nop, - optional: replaceInExpression, - zero_or_more: replaceInExpression, - one_or_more: replaceInExpression, - action: replaceInExpression, - - rule_ref: - function(node, from, to) { - if (node.name === from) { - node.name = to; - } - }, - - literal: nop, - any: nop, - "class": nop - }); - - replace(ast, from, to); - } - - var indices = []; - - each(ast.rules, function(rule, i) { - if (isProxyRule(rule)) { - replaceRuleRefs(ast, rule.name, rule.expression.name); - if (rule.name === ast.startRule) { - ast.startRule = rule.expression.name; - } - indices.push(i); - } - }); - - indices.reverse(); - - each(indices, function(index) { - ast.rules.splice(index, 1); - }); - }, - - /* - * Computes names of variables used for storing match results and parse - * positions in generated code. These variables are organized as two stacks. - * The following will hold after running this pass: - * - * * All nodes except "grammar" and "rule" nodes will have a |resultVar| - * property. It will contain a name of the variable that will store a - * match result of the expression represented by the node in generated - * code. - * - * * Some nodes will have a |posVar| property. It will contain a name of the - * variable that will store a parse position in generated code. - * - * * All "rule" nodes will contain |resultVars| and |posVars| properties. - * They will contain a list of values of |resultVar| and |posVar| - * properties used in rule's subnodes. (This is useful to declare - * variables in generated code.) - */ - computeVarNames: function(ast) { - function resultVar(index) { return "result" + index; } - function posVar(index) { return "pos" + index; } - - function computeLeaf(node, index) { - node.resultVar = resultVar(index.result); - - return { result: 0, pos: 0 }; - } - - function computeFromExpression(delta) { - return function(node, index) { - var depth = compute( - node.expression, - { - result: index.result + delta.result, - pos: index.pos + delta.pos - } - ); - - node.resultVar = resultVar(index.result); - if (delta.pos !== 0) { - node.posVar = posVar(index.pos); - } - - return { - result: depth.result + delta.result, - pos: depth.pos + delta.pos - }; - }; - } - - var compute = buildNodeVisitor({ - grammar: - function(node, index) { - each(node.rules, function(node) { - compute(node, index); - }); - }, - - rule: - function(node, index) { - var depth = compute(node.expression, index); - - node.resultVar = resultVar(index.result); - node.resultVars = map(range(depth.result + 1), resultVar); - node.posVars = map(range(depth.pos), posVar); - }, - - choice: - function(node, index) { - var depths = map(node.alternatives, function(alternative) { - return compute(alternative, index); - }); - - node.resultVar = resultVar(index.result); - - return { - result: Math.max.apply(null, pluck(depths, "result")), - pos: Math.max.apply(null, pluck(depths, "pos")) - }; - }, - - sequence: - function(node, index) { - var depths = map(node.elements, function(element, i) { - return compute( - element, - { result: index.result + i, pos: index.pos + 1 } - ); - }); - - node.resultVar = resultVar(index.result); - node.posVar = posVar(index.pos); - - return { - result: - node.elements.length > 0 - ? Math.max.apply( - null, - map(depths, function(d, i) { return i + d.result; }) - ) - : 0, - - pos: - node.elements.length > 0 - ? 1 + Math.max.apply(null, pluck(depths, "pos")) - : 1 - }; - }, - - labeled: computeFromExpression({ result: 0, pos: 0 }), - simple_and: computeFromExpression({ result: 0, pos: 1 }), - simple_not: computeFromExpression({ result: 0, pos: 1 }), - semantic_and: computeLeaf, - semantic_not: computeLeaf, - optional: computeFromExpression({ result: 0, pos: 0 }), - zero_or_more: computeFromExpression({ result: 1, pos: 0 }), - one_or_more: computeFromExpression({ result: 1, pos: 0 }), - action: computeFromExpression({ result: 0, pos: 1 }), - rule_ref: computeLeaf, - literal: computeLeaf, - any: computeLeaf, - "class": computeLeaf - }); - - compute(ast, { result: 0, pos: 0 }); - }, - - /* - * This pass walks through the AST and tracks what labels are visible at each - * point. For "action", "semantic_and" and "semantic_or" nodes it computes - * parameter names and values for the function used in generated code. (In the - * emitter, user's code is wrapped into a function that is immediately - * executed. Its parameter names correspond to visible labels and its - * parameter values to their captured values). Implicitly, this pass defines - * scoping rules for labels. - * - * After running this pass, all "action", "semantic_and" and "semantic_or" - * nodes will have a |params| property containing an object mapping parameter - * names to the expressions that will be used as their values. - */ - computeParams: function(ast) { - var envs = []; - - function scoped(f) { - envs.push({}); - f(); - envs.pop(); - } - - function nop() {} - - function computeForScopedExpression(node) { - scoped(function() { compute(node.expression); }); - } - - function computeParams(node) { - var env = envs[envs.length - 1], params = {}, name; - - for (name in env) { - params[name] = env[name]; - } - node.params = params; - } - - var compute = buildNodeVisitor({ - grammar: - function(node) { - each(node.rules, compute); - }, - - rule: computeForScopedExpression, - - choice: - function(node) { - scoped(function() { each(node.alternatives, compute); }); - }, - - sequence: - function(node) { - var env = envs[envs.length - 1], name; - - function fixup(name) { - each(pluck(node.elements, "resultVar"), function(resultVar, i) { - if ((new RegExp("^" + resultVar + "(\\[\\d+\\])*$")).test(env[name])) { - env[name] = node.resultVar + "[" + i + "]" - + env[name].substr(resultVar.length); - } - }); - } - - each(node.elements, compute); - - for (name in env) { - fixup(name); - } - }, - - labeled: - function(node) { - envs[envs.length - 1][node.label] = node.resultVar; - - scoped(function() { compute(node.expression); }); - }, - - simple_and: computeForScopedExpression, - simple_not: computeForScopedExpression, - semantic_and: computeParams, - semantic_not: computeParams, - optional: computeForScopedExpression, - zero_or_more: computeForScopedExpression, - one_or_more: computeForScopedExpression, - - action: - function(node) { - scoped(function() { - compute(node.expression); - computeParams(node); - }); - }, - - rule_ref: nop, - literal: nop, - any: nop, - "class": nop - }); - - compute(ast); - } -}; -/* Emits the generated code for the AST. */ -PEG.compiler.emitter = function(ast, options) { - options = options || {}; - if (options.cache === undefined) { - options.cache = false; - } - if (options.trackLineAndColumn === undefined) { - options.trackLineAndColumn = false; - } - - /* - * Codie 1.1.0 - * - * https://github.com/dmajda/codie - * - * Copyright (c) 2011-2012 David Majda - * Licensend under the MIT license. - */ - var Codie = (function(undefined) { - - function stringEscape(s) { - function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } - - /* - * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a - * string literal except for the closing quote character, backslash, - * carriage return, line separator, paragraph separator, and line feed. - * Any character may appear in the form of an escape sequence. - * - * For portability, we also escape escape all control and non-ASCII - * characters. Note that "\0" and "\v" escape sequences are not used - * because JSHint does not like the first and IE the second. - */ - return s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing double quote - .replace(/\x08/g, '\\b') // backspace - .replace(/\t/g, '\\t') // horizontal tab - .replace(/\n/g, '\\n') // line feed - .replace(/\f/g, '\\f') // form feed - .replace(/\r/g, '\\r') // carriage return - .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) - .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) - .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); - } - - function push(s) { return '__p.push(' + s + ');'; } - - function pushRaw(template, length, state) { - function unindent(code, level, unindentFirst) { - return code.replace( - new RegExp('^.{' + level +'}', "gm"), - function(str, offset) { - if (offset === 0) { - return unindentFirst ? '' : str; - } else { - return ""; - } - } - ); - } - - var escaped = stringEscape(unindent( - template.substring(0, length), - state.indentLevel(), - state.atBOL - )); - - return escaped.length > 0 ? push('"' + escaped + '"') : ''; - } - - - var Codie = { - /* Codie version (uses semantic versioning). */ - VERSION: "1.1.0", - - /* - * Specifies by how many characters do #if/#else and #for unindent their - * content in the generated code. - */ - indentStep: 2, - - /* Description of #-commands. Extend to define your own commands. */ - commands: { - "if": { - params: /^(.*)$/, - compile: function(state, prefix, params) { - return ['if(' + params[0] + '){', []]; - }, - stackOp: "push" - }, - "else": { - params: /^$/, - compile: function(state) { - var stack = state.commandStack, - insideElse = stack[stack.length - 1] === "else", - insideIf = stack[stack.length - 1] === "if"; - - if (insideElse) { throw new Error("Multiple #elses."); } - if (!insideIf) { throw new Error("Using #else outside of #if."); } - - return ['}else{', []]; - }, - stackOp: "replace" - }, - "for": { - params: /^([a-zA-Z_][a-zA-Z0-9_]*)[ \t]+in[ \t]+(.*)$/, - init: function(state) { - state.forCurrLevel = 0; // current level of #for loop nesting - state.forMaxLevel = 0; // maximum level of #for loop nesting - }, - compile: function(state, prefix, params) { - var c = '__c' + state.forCurrLevel, // __c for "collection" - l = '__l' + state.forCurrLevel, // __l for "length" - i = '__i' + state.forCurrLevel; // __i for "index" - - state.forCurrLevel++; - if (state.forMaxLevel < state.forCurrLevel) { - state.forMaxLevel = state.forCurrLevel; - } - - return [ - c + '=' + params[1] + ';' - + l + '=' + c + '.length;' - + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){' - + params[0] + '=' + c + '[' + i + '];', - [params[0], c, l, i] - ]; - }, - exit: function(state) { state.forCurrLevel--; }, - stackOp: "push" - }, - "end": { - params: /^$/, - compile: function(state) { - var stack = state.commandStack, exit; - - if (stack.length === 0) { throw new Error("Too many #ends."); } - - exit = Codie.commands[stack[stack.length - 1]].exit; - if (exit) { exit(state); } - - return ['}', []]; - }, - stackOp: "pop" - }, - "block": { - params: /^(.*)$/, - compile: function(state, prefix, params) { - var x = '__x', // __x for "prefix", - n = '__n', // __n for "lines" - l = '__l', // __l for "length" - i = '__i'; // __i for "index" - - /* - * Originally, the generated code used |String.prototype.replace|, but - * it is buggy in certain versions of V8 so it was rewritten. See the - * tests for details. - */ - return [ - x + '="' + stringEscape(prefix.substring(state.indentLevel())) + '";' - + n + '=(' + params[0] + ').toString().split("\\n");' - + l + '=' + n + '.length;' - + 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){' - + n + '[' + i +']=' + x + '+' + n + '[' + i + ']+"\\n";' - + '}' - + push(n + '.join("")'), - [x, n, l, i] - ]; - }, - stackOp: "nop" - } - }, - - /* - * Compiles a template into a function. When called, this function will - * execute the template in the context of an object passed in a parameter and - * return the result. - */ - template: function(template) { - var stackOps = { - push: function(stack, name) { stack.push(name); }, - replace: function(stack, name) { stack[stack.length - 1] = name; }, - pop: function(stack) { stack.pop(); }, - nop: function() { } - }; - - function compileExpr(state, expr) { - state.atBOL = false; - return [push(expr), []]; - } - - function compileCommand(state, prefix, name, params) { - var command, match, result; - - command = Codie.commands[name]; - if (!command) { throw new Error("Unknown command: #" + name + "."); } - - match = command.params.exec(params); - if (match === null) { - throw new Error( - "Invalid params for command #" + name + ": " + params + "." - ); - } - - result = command.compile(state, prefix, match.slice(1)); - stackOps[command.stackOp](state.commandStack, name); - state.atBOL = true; - return result; - } - - var state = { // compilation state - commandStack: [], // stack of commands as they were nested - atBOL: true, // is the next character to process at BOL? - indentLevel: function() { - return Codie.indentStep * this.commandStack.length; - } - }, - code = '', // generated template function code - vars = ['__p=[]'], // variables used by generated code - name, match, result, i; - - /* Initialize state. */ - for (name in Codie.commands) { - if (Codie.commands[name].init) { Codie.commands[name].init(state); } - } - - /* Compile the template. */ - while ((match = /^([ \t]*)#([a-zA-Z_][a-zA-Z0-9_]*)(?:[ \t]+([^ \t\n][^\n]*))?[ \t]*(?:\n|$)|#\{([^}]*)\}/m.exec(template)) !== null) { - code += pushRaw(template, match.index, state); - result = match[2] !== undefined && match[2] !== "" - ? compileCommand(state, match[1], match[2], match[3] || "") // #-command - : compileExpr(state, match[4]); // #{...} - code += result[0]; - vars = vars.concat(result[1]); - template = template.substring(match.index + match[0].length); - } - code += pushRaw(template, template.length, state); - - /* Check the final state. */ - if (state.commandStack.length > 0) { throw new Error("Missing #end."); } - - /* Sanitize the list of variables used by commands. */ - vars.sort(); - for (i = 0; i < vars.length; i++) { - if (vars[i] === vars[i - 1]) { vars.splice(i--, 1); } - } - - /* Create the resulting function. */ - return new Function("__v", [ - '__v=__v||{};', - 'var ' + vars.join(',') + ';', - 'with(__v){', - code, - 'return __p.join("").replace(/^\\n+|\\n+$/g,"");};' - ].join('')); - } - }; - - return Codie; - - })(); - - var templates = (function() { - var name, - templates = {}, - sources = { - grammar: [ - '(function(){', - ' /*', - ' * Generated by PEG.js 0.7.0.', - ' *', - ' * http://pegjs.majda.cz/', - ' */', - ' ', - /* This needs to be in sync with |quote| in utils.js. */ - ' function quote(s) {', - ' /*', - ' * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a', - ' * string literal except for the closing quote character, backslash,', - ' * carriage return, line separator, paragraph separator, and line feed.', - ' * Any character may appear in the form of an escape sequence.', - ' *', - ' * For portability, we also escape escape all control and non-ASCII', - ' * characters. Note that "\\0" and "\\v" escape sequences are not used', - ' * because JSHint does not like the first and IE the second.', - ' */', - ' return \'"\' + s', - ' .replace(/\\\\/g, \'\\\\\\\\\') // backslash', - ' .replace(/"/g, \'\\\\"\') // closing quote character', - ' .replace(/\\x08/g, \'\\\\b\') // backspace', - ' .replace(/\\t/g, \'\\\\t\') // horizontal tab', - ' .replace(/\\n/g, \'\\\\n\') // line feed', - ' .replace(/\\f/g, \'\\\\f\') // form feed', - ' .replace(/\\r/g, \'\\\\r\') // carriage return', - ' .replace(/[\\x00-\\x07\\x0B\\x0E-\\x1F\\x80-\\uFFFF]/g, escape)', - ' + \'"\';', - ' }', - ' ', - ' var result = {', - ' /*', - ' * Parses the input with a generated parser. If the parsing is successfull,', - ' * returns a value explicitly or implicitly specified by the grammar from', - ' * which the parser was generated (see |PEG.buildParser|). If the parsing is', - ' * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.', - ' */', - ' parse: function(input, startRule) {', - ' var parseFunctions = {', - ' #for rule in node.rules', - ' #{string(rule.name) + ": parse_" + rule.name + (rule !== node.rules[node.rules.length - 1] ? "," : "")}', - ' #end', - ' };', - ' ', - ' if (startRule !== undefined) {', - ' if (parseFunctions[startRule] === undefined) {', - ' throw new Error("Invalid rule name: " + quote(startRule) + ".");', - ' }', - ' } else {', - ' startRule = #{string(node.startRule)};', - ' }', - ' ', - ' #{posInit("pos")};', - ' var reportFailures = 0;', // 0 = report, anything > 0 = do not report - ' #{posInit("rightmostFailuresPos")};', - ' var rightmostFailuresExpected = [];', - ' #if options.cache', - ' var cache = {};', - ' #end', - ' ', - /* This needs to be in sync with |padLeft| in utils.js. */ - ' function padLeft(input, padding, length) {', - ' var result = input;', - ' ', - ' var padLength = length - input.length;', - ' for (var i = 0; i < padLength; i++) {', - ' result = padding + result;', - ' }', - ' ', - ' return result;', - ' }', - ' ', - /* This needs to be in sync with |escape| in utils.js. */ - ' function escape(ch) {', - ' var charCode = ch.charCodeAt(0);', - ' var escapeChar;', - ' var length;', - ' ', - ' if (charCode <= 0xFF) {', - ' escapeChar = \'x\';', - ' length = 2;', - ' } else {', - ' escapeChar = \'u\';', - ' length = 4;', - ' }', - ' ', - ' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);', - ' }', - ' ', - ' #if options.trackLineAndColumn', - ' function clone(object) {', - ' var result = {};', - ' for (var key in object) {', - ' result[key] = object[key];', - ' }', - ' return result;', - ' }', - ' ', - ' function advance(pos, n) {', - ' var endOffset = pos.offset + n;', - ' ', - ' for (var offset = pos.offset; offset < endOffset; offset++) {', - ' var ch = input.charAt(offset);', - ' if (ch === "\\n") {', - ' if (!pos.seenCR) { pos.line++; }', - ' pos.column = 1;', - ' pos.seenCR = false;', - ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {', - ' pos.line++;', - ' pos.column = 1;', - ' pos.seenCR = true;', - ' } else {', - ' pos.column++;', - ' pos.seenCR = false;', - ' }', - ' }', - ' ', - ' pos.offset += n;', - ' }', - ' ', - ' #end', - ' function matchFailed(failure) {', - ' if (#{posOffset("pos")} < #{posOffset("rightmostFailuresPos")}) {', - ' return;', - ' }', - ' ', - ' if (#{posOffset("pos")} > #{posOffset("rightmostFailuresPos")}) {', - ' rightmostFailuresPos = #{posClone("pos")};', - ' rightmostFailuresExpected = [];', - ' }', - ' ', - ' rightmostFailuresExpected.push(failure);', - ' }', - ' ', - ' #for rule in node.rules', - ' #block emit(rule)', - ' ', - ' #end', - ' ', - ' function cleanupExpected(expected) {', - ' expected.sort();', - ' ', - ' var lastExpected = null;', - ' var cleanExpected = [];', - ' for (var i = 0; i < expected.length; i++) {', - ' if (expected[i] !== lastExpected) {', - ' cleanExpected.push(expected[i]);', - ' lastExpected = expected[i];', - ' }', - ' }', - ' return cleanExpected;', - ' }', - ' ', - ' #if !options.trackLineAndColumn', - ' function computeErrorPosition() {', - ' /*', - ' * The first idea was to use |String.split| to break the input up to the', - ' * error position along newlines and derive the line and column from', - ' * there. However IE\'s |split| implementation is so broken that it was', - ' * enough to prevent it.', - ' */', - ' ', - ' var line = 1;', - ' var column = 1;', - ' var seenCR = false;', - ' ', - ' for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {', - ' var ch = input.charAt(i);', - ' if (ch === "\\n") {', - ' if (!seenCR) { line++; }', - ' column = 1;', - ' seenCR = false;', - ' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {', - ' line++;', - ' column = 1;', - ' seenCR = true;', - ' } else {', - ' column++;', - ' seenCR = false;', - ' }', - ' }', - ' ', - ' return { line: line, column: column };', - ' }', - ' #end', - ' ', - ' #if node.initializer', - ' #block emit(node.initializer)', - ' #end', - ' ', - ' var result = parseFunctions[startRule]();', - ' ', - ' /*', - ' * The parser is now in one of the following three states:', - ' *', - ' * 1. The parser successfully parsed the whole input.', - ' *', - ' * - |result !== null|', - ' * - |#{posOffset("pos")} === input.length|', - ' * - |rightmostFailuresExpected| may or may not contain something', - ' *', - ' * 2. The parser successfully parsed only a part of the input.', - ' *', - ' * - |result !== null|', - ' * - |#{posOffset("pos")} < input.length|', - ' * - |rightmostFailuresExpected| may or may not contain something', - ' *', - ' * 3. The parser did not successfully parse any part of the input.', - ' *', - ' * - |result === null|', - ' * - |#{posOffset("pos")} === 0|', - ' * - |rightmostFailuresExpected| contains at least one failure', - ' *', - ' * All code following this comment (including called functions) must', - ' * handle these states.', - ' */', - ' if (result === null || #{posOffset("pos")} !== input.length) {', - ' var offset = Math.max(#{posOffset("pos")}, #{posOffset("rightmostFailuresPos")});', - ' var found = offset < input.length ? input.charAt(offset) : null;', - ' #if options.trackLineAndColumn', - ' var errorPosition = #{posOffset("pos")} > #{posOffset("rightmostFailuresPos")} ? pos : rightmostFailuresPos;', - ' #else', - ' var errorPosition = computeErrorPosition();', - ' #end', - ' ', - ' throw new this.SyntaxError(', - ' cleanupExpected(rightmostFailuresExpected),', - ' found,', - ' offset,', - ' errorPosition.line,', - ' errorPosition.column', - ' );', - ' }', - ' ', - ' return result;', - ' },', - ' ', - ' /* Returns the parser source code. */', - ' toSource: function() { return this._source; }', - ' };', - ' ', - ' /* Thrown when a parser encounters a syntax error. */', - ' ', - ' result.SyntaxError = function(expected, found, offset, line, column) {', - ' function buildMessage(expected, found) {', - ' var expectedHumanized, foundHumanized;', - ' ', - ' switch (expected.length) {', - ' case 0:', - ' expectedHumanized = "end of input";', - ' break;', - ' case 1:', - ' expectedHumanized = expected[0];', - ' break;', - ' default:', - ' expectedHumanized = expected.slice(0, expected.length - 1).join(", ")', - ' + " or "', - ' + expected[expected.length - 1];', - ' }', - ' ', - ' foundHumanized = found ? quote(found) : "end of input";', - ' ', - ' return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";', - ' }', - ' ', - ' this.name = "SyntaxError";', - ' this.expected = expected;', - ' this.found = found;', - ' this.message = buildMessage(expected, found);', - ' this.offset = offset;', - ' this.line = line;', - ' this.column = column;', - ' };', - ' ', - ' result.SyntaxError.prototype = Error.prototype;', - ' ', - ' return result;', - '})()' - ], - rule: [ - 'function parse_#{node.name}() {', - ' #if options.cache', - ' var cacheKey = "#{node.name}@" + #{posOffset("pos")};', - ' var cachedResult = cache[cacheKey];', - ' if (cachedResult) {', - ' pos = #{posClone("cachedResult.nextPos")};', - ' return cachedResult.result;', - ' }', - ' ', - ' #end', - ' #if node.resultVars.length > 0', - ' var #{node.resultVars.join(", ")};', - ' #end', - ' #if node.posVars.length > 0', - ' var #{node.posVars.join(", ")};', - ' #end', - ' ', - ' #if node.displayName !== null', - ' reportFailures++;', - ' #end', - ' #block emit(node.expression)', - ' #if node.displayName !== null', - ' reportFailures--;', - ' if (reportFailures === 0 && #{node.resultVar} === null) {', - ' matchFailed(#{string(node.displayName)});', - ' }', - ' #end', - ' #if options.cache', - ' ', - ' cache[cacheKey] = {', - ' nextPos: #{posClone("pos")},', - ' result: #{node.resultVar}', - ' };', - ' #end', - ' return #{node.resultVar};', - '}' - ], - choice: [ - '#block emit(alternative)', - '#block nextAlternativesCode' - ], - "choice.next": [ - 'if (#{node.resultVar} === null) {', - ' #block code', - '}' - ], - sequence: [ - '#{posSave(node)};', - '#block code' - ], - "sequence.iteration": [ - '#block emit(element)', - 'if (#{element.resultVar} !== null) {', - ' #block code', - '} else {', - ' #{node.resultVar} = null;', - ' #{posRestore(node)};', - '}' - ], - "sequence.inner": [ - '#{node.resultVar} = [#{pluck(node.elements, "resultVar").join(", ")}];' - ], - simple_and: [ - '#{posSave(node)};', - 'reportFailures++;', - '#block emit(node.expression)', - 'reportFailures--;', - 'if (#{node.resultVar} !== null) {', - ' #{node.resultVar} = "";', - ' #{posRestore(node)};', - '} else {', - ' #{node.resultVar} = null;', - '}' - ], - simple_not: [ - '#{posSave(node)};', - 'reportFailures++;', - '#block emit(node.expression)', - 'reportFailures--;', - 'if (#{node.resultVar} === null) {', - ' #{node.resultVar} = "";', - '} else {', - ' #{node.resultVar} = null;', - ' #{posRestore(node)};', - '}' - ], - semantic_and: [ - '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? "" : null;' - ], - semantic_not: [ - '#{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? ["pos.offset", "pos.line", "pos.column"] : ["pos"]).concat(values(node.params)).join(", ")}) ? null : "";' - ], - optional: [ - '#block emit(node.expression)', - '#{node.resultVar} = #{node.resultVar} !== null ? #{node.resultVar} : "";' - ], - zero_or_more: [ - '#{node.resultVar} = [];', - '#block emit(node.expression)', - 'while (#{node.expression.resultVar} !== null) {', - ' #{node.resultVar}.push(#{node.expression.resultVar});', - ' #block emit(node.expression)', - '}' - ], - one_or_more: [ - '#block emit(node.expression)', - 'if (#{node.expression.resultVar} !== null) {', - ' #{node.resultVar} = [];', - ' while (#{node.expression.resultVar} !== null) {', - ' #{node.resultVar}.push(#{node.expression.resultVar});', - ' #block emit(node.expression)', - ' }', - '} else {', - ' #{node.resultVar} = null;', - '}' - ], - action: [ - '#{posSave(node)};', - '#block emit(node.expression)', - 'if (#{node.resultVar} !== null) {', - ' #{node.resultVar} = (function(#{(options.trackLineAndColumn ? ["offset", "line", "column"] : ["offset"]).concat(keys(node.params)).join(", ")}) {#{node.code}})(#{(options.trackLineAndColumn ? [node.posVar + ".offset", node.posVar + ".line", node.posVar + ".column"] : [node.posVar]).concat(values(node.params)).join(", ")});', - '}', - 'if (#{node.resultVar} === null) {', - ' #{posRestore(node)};', - '}' - ], - rule_ref: [ - '#{node.resultVar} = parse_#{node.name}();' - ], - literal: [ - '#if node.value.length === 0', - ' #{node.resultVar} = "";', - '#else', - ' #if !node.ignoreCase', - ' #if node.value.length === 1', - ' if (input.charCodeAt(#{posOffset("pos")}) === #{node.value.charCodeAt(0)}) {', - ' #else', - ' if (input.substr(#{posOffset("pos")}, #{node.value.length}) === #{string(node.value)}) {', - ' #end', - ' #else', - /* - * One-char literals are not optimized when case-insensitive - * matching is enabled. This is because there is no simple way to - * lowercase a character code that works for character outside ASCII - * letters. Moreover, |toLowerCase| can change string length, - * meaning the result of lowercasing a character can be more - * characters. - */ - ' if (input.substr(#{posOffset("pos")}, #{node.value.length}).toLowerCase() === #{string(node.value.toLowerCase())}) {', - ' #end', - ' #if !node.ignoreCase', - ' #{node.resultVar} = #{string(node.value)};', - ' #else', - ' #{node.resultVar} = input.substr(#{posOffset("pos")}, #{node.value.length});', - ' #end', - ' #{posAdvance(node.value.length)};', - ' } else {', - ' #{node.resultVar} = null;', - ' if (reportFailures === 0) {', - ' matchFailed(#{string(string(node.value))});', - ' }', - ' }', - '#end' - ], - any: [ - 'if (input.length > #{posOffset("pos")}) {', - ' #{node.resultVar} = input.charAt(#{posOffset("pos")});', - ' #{posAdvance(1)};', - '} else {', - ' #{node.resultVar} = null;', - ' if (reportFailures === 0) {', - ' matchFailed("any character");', - ' }', - '}' - ], - "class": [ - 'if (#{regexp}.test(input.charAt(#{posOffset("pos")}))) {', - ' #{node.resultVar} = input.charAt(#{posOffset("pos")});', - ' #{posAdvance(1)};', - '} else {', - ' #{node.resultVar} = null;', - ' if (reportFailures === 0) {', - ' matchFailed(#{string(node.rawText)});', - ' }', - '}' - ] - }; - - for (name in sources) { - templates[name] = Codie.template(sources[name].join('\n')); - } - - return templates; - })(); - - function fill(name, vars) { - vars.string = quote; - vars.pluck = pluck; - vars.keys = keys; - vars.values = values; - vars.emit = emit; - vars.options = options; - - /* Position-handling macros */ - if (options.trackLineAndColumn) { - vars.posInit = function(name) { - return "var " - + name - + " = " - + "{ offset: 0, line: 1, column: 1, seenCR: false }"; - }; - vars.posClone = function(name) { return "clone(" + name + ")"; }; - vars.posOffset = function(name) { return name + ".offset"; }; - - vars.posAdvance = function(n) { return "advance(pos, " + n + ")"; }; - } else { - vars.posInit = function(name) { return "var " + name + " = 0"; }; - vars.posClone = function(name) { return name; }; - vars.posOffset = function(name) { return name; }; - - vars.posAdvance = function(n) { - return n === 1 ? "pos++" : "pos += " + n; - }; - } - vars.posSave = function(node) { - return node.posVar + " = " + vars.posClone("pos"); - }; - vars.posRestore = function(node) { - return "pos" + " = " + vars.posClone(node.posVar); - }; - - return templates[name](vars); - } - - function emitSimple(name) { - return function(node) { return fill(name, { node: node }); }; - } - - var emit = buildNodeVisitor({ - grammar: emitSimple("grammar"), - - initializer: function(node) { return node.code; }, - - rule: emitSimple("rule"), - - /* - * The contract for all code fragments generated by the following functions - * is as follows. - * - * The code fragment tries to match a part of the input starting with the - * position indicated in |pos|. That position may point past the end of the - * input. - * - * * If the code fragment matches the input, it advances |pos| to point to - * the first chracter following the matched part of the input and sets - * variable with a name stored in |node.resultVar| to an appropriate - * value. This value is always non-|null|. - * - * * If the code fragment does not match the input, it returns with |pos| - * set to the original value and it sets a variable with a name stored in - * |node.resultVar| to |null|. - * - * The code can use variables with names stored in |resultVar| and |posVar| - * properties of the current node's subnodes. It can't use any other - * variables. - */ - - choice: function(node) { - var code, nextAlternativesCode; - - for (var i = node.alternatives.length - 1; i >= 0; i--) { - nextAlternativesCode = i !== node.alternatives.length - 1 - ? fill("choice.next", { node: node, code: code }) - : ''; - code = fill("choice", { - alternative: node.alternatives[i], - nextAlternativesCode: nextAlternativesCode - }); - } - - return code; - }, - - sequence: function(node) { - var code = fill("sequence.inner", { node: node }); - - for (var i = node.elements.length - 1; i >= 0; i--) { - code = fill("sequence.iteration", { - node: node, - element: node.elements[i], - code: code - }); - } - - return fill("sequence", { node: node, code: code }); - }, - - labeled: function(node) { return emit(node.expression); }, - - simple_and: emitSimple("simple_and"), - simple_not: emitSimple("simple_not"), - semantic_and: emitSimple("semantic_and"), - semantic_not: emitSimple("semantic_not"), - optional: emitSimple("optional"), - zero_or_more: emitSimple("zero_or_more"), - one_or_more: emitSimple("one_or_more"), - action: emitSimple("action"), - rule_ref: emitSimple("rule_ref"), - literal: emitSimple("literal"), - any: emitSimple("any"), - - "class": function(node) { - var regexp; - - if (node.parts.length > 0) { - regexp = '/^[' - + (node.inverted ? '^' : '') - + map(node.parts, function(part) { - return part instanceof Array - ? quoteForRegexpClass(part[0]) - + '-' - + quoteForRegexpClass(part[1]) - : quoteForRegexpClass(part); - }).join('') - + ']/' + (node.ignoreCase ? 'i' : ''); - } else { - /* - * Stupid IE considers regexps /[]/ and /[^]/ syntactically invalid, so - * we translate them into euqivalents it can handle. - */ - regexp = node.inverted ? '/^[\\S\\s]/' : '/^(?!)/'; - } - - return fill("class", { node: node, regexp: regexp }); - } - }); - - return emit(ast); -}; - -return PEG; - -})(); - -if (typeof module !== "undefined") { - module.exports = PEG; -} diff --git a/vendor/plist.js b/vendor/plist.js deleted file mode 100644 index f4110e934..000000000 --- a/vendor/plist.js +++ /dev/null @@ -1,220 +0,0 @@ -;(function (exports, sax) { - //Checks if running in a non-browser environment - var inNode = typeof window === 'undefined' ? true : false; - - function Parser() { - sax.SAXParser.call(this, false, { lowercasetags: true, trim: false }); - } - - var inherits = null; - if (inNode) { - var fs = require('fs'); - inherits = require('util').inherits; //use node provided function - } else { //use in browser - if ("create" in Object) { - inherits = function(ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; - } else { - var klass = function() {}; - inherits = function(ctor, superCtor) { - klass.prototype = superCtor.prototype; - ctor.prototype = new klass; - ctor.prototype['constructor'] = ctor; - } - } - } - inherits(Parser, sax.SAXParser); //inherit from sax (browser-style or node-style) - - Parser.prototype.getInteger = function (string) { - this.value = parseInt(string, 10); - } - Parser.prototype.getReal = function (string) { - this.value = parseFloat(string); - } - Parser.prototype.getString = function (string) { - this.value += string; - } - Parser.prototype.getData = function(string) { - // todo: parse base64 encoded data - this.value += string; - } - Parser.prototype.getDate = function (string) { - this.value = new Date(string); - } - - Parser.prototype.addToDict = function (value) { - this.dict[this.key] = value; - } - Parser.prototype.addToArray = function (value) { - this.array.push(value); - } - - Parser.prototype.onopentag = function (tag) { - switch (tag.name) { - case 'dict': - this.stack.push(this.context); - this.context = { - value: function() { - return this.dict; - }, - dict: {}, - setKey: function(key) { - this.key = key; - }, - setValue: function(value) { - this.dict[this.key] = value; - } - } - break; - case 'plist': - case 'array': - this.stack.push(this.context); - this.context = { - value: function() { - return this.array; - }, - array: [], - setKey: function(key) { - console.log('unexpected element in array'); - }, - setValue: function(value) { - this.array.push(value); - } - } - break; - case 'key': - this.ontext = function (text) { - this.context.setKey(text); - } - break; - case 'integer': - this.ontext = this.getInteger; - break; - case 'real': - this.ontext = this.getReal; - break; - case 'string': - this.value = ''; - this.ontext = this.getString; - this.oncdata = this.getString; - break; - case 'data': - this.value = ''; - this.ontext = this.getData; - this.oncdata = this.getData; - break; - case 'true': - this.value = true; - break; - case 'false': - this.value = false; - break; - case 'date': - this.ontext = this.getDate; - break; - default: - console.log('ignored tag', tag.name); - break; - } - } - Parser.prototype.onclosetag = function (tag) { - var value; - switch (tag) { - case 'dict': - case 'array': - case 'plist': - var value = this.context.value(); - this.context = this.stack.pop(); - this.context.setValue(value); - break; - case 'true': - case 'false': - case 'string': - case 'integer': - case 'real': - case 'date': - case 'data': - this.context.setValue(this.value); - break; - case 'key': - break; - default: - console.log('closing', tag, 'tag ignored'); - } - this.oncdata = this.ontext = this.checkWhitespace; - } - Parser.prototype.checkWhitespace = function (data) { - if (!data.match(/^[ \t\r\n]*$/)) { - console.log('unexpected non-whitespace data', data); - } - } - Parser.prototype.oncomment = function (comment) { - } - Parser.prototype.onerror = function (error) { - console.log('sax parser error:', error); - throw error; - } - - if (inNode) Parser.prototype.parseFile = function (xmlfile, callback) { //browsers aren't capable of opening files, instead use AJAX - var parser = this; - parser.stack = [ ]; - parser.context = { - callback: callback, - value: function() {}, - setKey: function(key) {}, - setValue: function(value) { - callback(null, value); - }, - } - var rs = fs.createReadStream(xmlfile, { - encoding: 'utf8' - }); - rs.on('data', function(data) { parser.write(data); }); - rs.on('end', function() { parser.close(); }); - } - - Parser.prototype.parseString = function (xml, callback) { - var parser = this; - parser.stack = [ ]; - parser.context = { - callback: callback, - value: function() {}, - setKey: function(key) {}, - setValue: function(value) { - this.callback(null, value); - }, - }; - - try { - parser.write(xml); - parser.close(); - } - catch (e) { - callback(e, {}) - } - } - - exports.Parser = Parser; - - exports.parseString = function (xml, callback) { - var parser = new Parser(); - parser.parseString(xml, callback); - } - - if (inNode) exports.parseFile = function (filename, callback) { //Do not expose no created method - var parser = new Parser(); - parser.parseFile(filename, callback); - } -})(typeof exports === 'undefined' ? plist = {} : exports, require('sax')) // Changed by sobo to always `require` sax -//the above line checks for exports (defined in node) and uses it, or creates a global variable and exports to that. -//also, if in node, require sax node-style, in browser the developer must use a