+++ /dev/null
-(function(global) {
- var FlappAction= function() {
- this.actionRecord = null;
- };
- FlappAction.exec = function(tag, movieClip, rootMovieClip) {
- console.debug("FlappAction.exec");
- var actionsBit = new FlappIBit();
- actionsBit.input(tag.actions);
- var code = 0;
- var stack = [];
- while (code = actionsBit.ui8()) {
- if (code < 0x80) {
- switch (code) {
- case 0x06: // Play
- movieClip.play();
- break;
- case 0x07: // Stop
- movieClip.stop();
- break;
- case 0x1d: // SetVariables
- movieClip.setVariable(stack.pop(), stack.pop());
- break;
- default:
- console.debug("FlappActiom: not implemented yet. code=0x%02x", code);
- break;
- }
- } else {
- var actionLength = actionsBit.input(tag.actions);
- var nextActionOffset = actionsBit.getBytePos() + actionLength;
- switch (code) {
- case 0x81: // GotoFrame
- movieClip.gotoFrame(actionsBit.si16());
- break;
- case 0x83: // GetURL
- //
- break;
- case 0x8c: // GoToLabel
- movieClip.gotoLabel(actionsBit.strN(actionLength));
- break;
- //case 0x96: // Push
- default:
- console.debug("FlappActiom: not implemented yet. code=0x%02x", code);
- break;
- }
- actionsBit.setPos(nextActionOffset, 0);
- }
- }
- };
- global.FlappAction = FlappAction;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappBitmap = function() {
- ;
- };
- FlappBitmap.prototype = {
-
- };
- FlappBitmap.jpegChunkOffsets = function(jpegData) {
- var offsetTable = {};
- var ibit = new FlappIBit();
- while (ibit.HasNext(2)) {
- var marker = ibit.ui16be();
- var offset = ibit.getBytePos();
- switch (marker) {
- case 0xFFD8: // SOI
- case 0xFFD9: // EOI
- break;
- case 0xFFDA: // SOS + [RST] + EOI
- length = ibit.len() - offset;
- offsetTable[marker] = [offset, length]
- break;
- default:
- length = ibit.ui16be() + 2;
- offsetTable[marker] = [offset, length]
-
- break;
- }
- }
- return offsetTable;
- }
-
- FlappBitmap.toJpeg = function(swfJpeg, jpegTables) {
- var offsetTable = FlappBitmap.jpegChunkOffsets(swfJpeg);
- var hasDQT = (0xFFDB in offsetTable)?true:false;
- if (hasDQT === false) {
- var offsetTable2 = FlappBitmap.jpegChunkOffsets(jpegTables);
- }
- var jpegArray = [0xFF, 0xD8]; // SOI
- // APP0, SOF0, DQT, DHT, SOS
- var jpegOrder = [0xFFE0, 0xFFC0, 0xFFDB, 0xFFC4, 0xFFDA];
- for (var i = 0, l = jpegOrder; i < l ; i++) {
- var marker = jpegOrder[i];
- var swfJpegOffset = (marker in offsetTable)?true:false;
- if (swfJpegOffset) {
- var entry = offsetTable[marker];
- } else {
- var entry = offsetTable2[marker];
- }
- var offset = entry[0];
- var enfoffset = offset + entry[1];
- for (j = offset; j < enfoffset ; j++) {
- if (swfJpegOffset) {
- jpegArray.join(swfJpeg[j]);
- } else {
- jpegArray.join(jpegTables[j]);
- }
- }
- }
- return FlappString.ArrayToString(jpegArray).join('');
- };
- FlappBitmap.toPng = function(lossless) {
- ;
- };
- global.FlappBitmap = FlappBitmap;
-})(this);
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<project name="project" default="all" >
+ <property name="level" value="ADVANCED_OPTIMIZATIONS"/>
+ <property name="src" value="./src"/>
+ <property name="vendor" value="./vendor"/>
+ <property name="bin" value="./bin"/>
+ <property name="compiler" value="build/compiler.jar"/>
+ <property name="closure_primitives" value="closure-primitives/base.js"/>
+ <property name="depswriter" value="closure-primitives/depswriter.py"/>
+ <property name="depend" value="deps.js"/>
+
+ <!-- ビルドの事前準備 -->
+ <target name="prebuild" description="ビルドの事前準備を行う">
+ <mkdir dir="${bin}"/>
+ </target>
+
+ <!-- 依存関係を解決する -->
+ <target name="deps" description="依存関係を解決する">
+ <exec executable="python" failonerror="true">
+ <arg line="${depswriter}"/>
+ <arg line="--root_with_prefix=". ..""/>
+ <arg line="--output_file=${depend}"/>
+ </exec>
+ <fileset dir="${src}" includes="**/*.js" id="srcpath"/>
+ <pathconvert property="srcfiles" refid="srcpath" pathsep=" "/>
+ <echo message="${srcfiles}"/>
+ </target>
+
+ <!-- ビルド -->
+ <target name="build" depends="deps,prebuild" description="ビルドを行う">
+ <!-- 出力ファイル名 -->
+ <local name="outfile"/>
+ <property name="outfile" value="${bin}/flapp.js"/>
+ <!-- ビルド -->
+ <java jar="${compiler}" fork="true" failonerror="true">
+ <arg line="--warning_level=VERBOSE"/>
+ <arg line="--compilation_level=${level}"/>
+ <arg line="--define=goog.DEBUG=false"/>
+ <arg line="--externs=console.js"/>
+ <arg line="--output_wrapper='(function() {%output%}).call(this);'"/>
+ <arg line="--summary_detail_level=3"/>
+ <arg line="--language_in=ECMASCRIPT5_STRICT"/>
+ <arg line="--js_output_file=${outfile}"/>
+ <arg line="--js=${closure_primitives}"/>
+ <arg line="--js=${depend}"/>
+ <arg line="${srcfiles}"/>
+ </java>
+ </target>
+
+ <!-- compiler help -->
+ <target name="help">
+ <java jar="${compiler}" fork="true" failonerror="true">
+ <arg line="--help"/>
+ </java>
+ </target>
+
+ <!-- 全て作成 -->
+ <target name="all" depends="build" />
+
+ <!-- 削除 -->
+ <target name="clean">
+ <delete file="${depend}"/>
+ <delete dir="${bin}"/>
+ </target>
+
+ <!-- リビルド -->
+ <target name="rebuild" depends="clean,all"/>
+</project>
+++ /dev/null
-(function(global) {
- var FlappCanvas = function(canvas) {
- this.canvas = canvas;
- this.ctx = canvas.getContext('2d');
- };
- FlappCanvas.prototype = {
-
- }
- global.FlappCanvas = FlappCanvas;
-})(this);
--- /dev/null
+// Copyright 2006 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Bootstrap for the Google JS Library (Closure).
+ *
+ * In uncompiled mode base.js will write out Closure's deps file, unless the
+ * global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects to
+ * include their own deps file(s) from different locations.
+ *
+ *
+ * @provideGoog
+ */
+
+
+/**
+ * @define {boolean} Overridden to true by the compiler when --closure_pass
+ * or --mark_as_compiled is specified.
+ */
+var COMPILED = false;
+
+
+/**
+ * Base namespace for the Closure library. Checks to see goog is
+ * already defined in the current scope before assigning to prevent
+ * clobbering if base.js is loaded more than once.
+ *
+ * @const
+ */
+var goog = goog || {}; // Identifies this file as the Closure base.
+
+
+/**
+ * Reference to the global context. In most cases this will be 'window'.
+ */
+goog.global = this;
+
+
+/**
+ * @define {boolean} DEBUG is provided as a convenience so that debugging code
+ * that should not be included in a production js_binary can be easily stripped
+ * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most
+ * toString() methods should be declared inside an "if (goog.DEBUG)" conditional
+ * because they are generally used for debugging purposes and it is difficult
+ * for the JSCompiler to statically determine whether they are used.
+ */
+goog.DEBUG = true;
+
+
+/**
+ * @define {string} LOCALE defines the locale being used for compilation. It is
+ * used to select locale specific data to be compiled in js binary. BUILD rule
+ * can specify this value by "--define goog.LOCALE=<locale_name>" as JSCompiler
+ * option.
+ *
+ * Take into account that the locale code format is important. You should use
+ * the canonical Unicode format with hyphen as a delimiter. Language must be
+ * lowercase, Language Script - Capitalized, Region - UPPERCASE.
+ * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.
+ *
+ * See more info about locale codes here:
+ * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers
+ *
+ * For language codes you should use values defined by ISO 693-1. See it here
+ * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from
+ * this rule: the Hebrew language. For legacy reasons the old code (iw) should
+ * be used instead of the new code (he), see http://wiki/Main/IIISynonyms.
+ */
+goog.LOCALE = 'en'; // default to en
+
+
+/**
+ * Creates object stubs for a namespace. The presence of one or more
+ * goog.provide() calls indicate that the file defines the given
+ * objects/namespaces. Build tools also scan for provide/require statements
+ * to discern dependencies, build dependency files (see deps.js), etc.
+ * @see goog.require
+ * @param {string} name Namespace provided by this file in the form
+ * "goog.package.part".
+ */
+goog.provide = function(name) {
+ if (!COMPILED) {
+ // Ensure that the same namespace isn't provided twice. This is intended
+ // to teach new developers that 'goog.provide' is effectively a variable
+ // declaration. And when JSCompiler transforms goog.provide into a real
+ // variable declaration, the compiled JS should work the same as the raw
+ // JS--even when the raw JS uses goog.provide incorrectly.
+ if (goog.isProvided_(name)) {
+ throw Error('Namespace "' + name + '" already declared.');
+ }
+ delete goog.implicitNamespaces_[name];
+
+ var namespace = name;
+ while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
+ if (goog.getObjectByName(namespace)) {
+ break;
+ }
+ goog.implicitNamespaces_[namespace] = true;
+ }
+ }
+
+ goog.exportPath_(name);
+};
+
+
+/**
+ * Marks that the current file should only be used for testing, and never for
+ * live code in production.
+ * @param {string=} opt_message Optional message to add to the error that's
+ * raised when used in production code.
+ */
+goog.setTestOnly = function(opt_message) {
+ if (COMPILED && !goog.DEBUG) {
+ opt_message = opt_message || '';
+ throw Error('Importing test-only code into non-debug environment' +
+ opt_message ? ': ' + opt_message : '.');
+ }
+};
+
+
+if (!COMPILED) {
+
+ /**
+ * Check if the given name has been goog.provided. This will return false for
+ * names that are available only as implicit namespaces.
+ * @param {string} name name of the object to look for.
+ * @return {boolean} Whether the name has been provided.
+ * @private
+ */
+ goog.isProvided_ = function(name) {
+ return !goog.implicitNamespaces_[name] && !!goog.getObjectByName(name);
+ };
+
+ /**
+ * Namespaces implicitly defined by goog.provide. For example,
+ * goog.provide('goog.events.Event') implicitly declares
+ * that 'goog' and 'goog.events' must be namespaces.
+ *
+ * @type {Object}
+ * @private
+ */
+ goog.implicitNamespaces_ = {};
+}
+
+
+/**
+ * Builds an object structure for the provided namespace path,
+ * ensuring that names that already exist are not overwritten. For
+ * example:
+ * "a.b.c" -> a = {};a.b={};a.b.c={};
+ * Used by goog.provide and goog.exportSymbol.
+ * @param {string} name name of the object that this file defines.
+ * @param {*=} opt_object the object to expose at the end of the path.
+ * @param {Object=} opt_objectToExportTo The object to add the path to; default
+ * is |goog.global|.
+ * @private
+ */
+goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
+ var parts = name.split('.');
+ var cur = opt_objectToExportTo || goog.global;
+
+ // Internet Explorer exhibits strange behavior when throwing errors from
+ // methods externed in this manner. See the testExportSymbolExceptions in
+ // base_test.html for an example.
+ if (!(parts[0] in cur) && cur.execScript) {
+ cur.execScript('var ' + parts[0]);
+ }
+
+ // Certain browsers cannot parse code in the form for((a in b); c;);
+ // This pattern is produced by the JSCompiler when it collapses the
+ // statement above into the conditional loop below. To prevent this from
+ // happening, use a for-loop and reserve the init logic as below.
+
+ // Parentheses added to eliminate strict JS warning in Firefox.
+ for (var part; parts.length && (part = parts.shift());) {
+ if (!parts.length && goog.isDef(opt_object)) {
+ // last part and we have an object; use it
+ cur[part] = opt_object;
+ } else if (cur[part]) {
+ cur = cur[part];
+ } else {
+ cur = cur[part] = {};
+ }
+ }
+};
+
+
+/**
+ * Returns an object based on its fully qualified external name. If you are
+ * using a compilation pass that renames property names beware that using this
+ * function will not find renamed properties.
+ *
+ * @param {string} name The fully qualified name.
+ * @param {Object=} opt_obj The object within which to look; default is
+ * |goog.global|.
+ * @return {?} The value (object or primitive) or, if not found, null.
+ */
+goog.getObjectByName = function(name, opt_obj) {
+ var parts = name.split('.');
+ var cur = opt_obj || goog.global;
+ for (var part; part = parts.shift(); ) {
+ if (goog.isDefAndNotNull(cur[part])) {
+ cur = cur[part];
+ } else {
+ return null;
+ }
+ }
+ return cur;
+};
+
+
+/**
+ * Globalizes a whole namespace, such as goog or goog.lang.
+ *
+ * @param {Object} obj The namespace to globalize.
+ * @param {Object=} opt_global The object to add the properties to.
+ * @deprecated Properties may be explicitly exported to the global scope, but
+ * this should no longer be done in bulk.
+ */
+goog.globalize = function(obj, opt_global) {
+ var global = opt_global || goog.global;
+ for (var x in obj) {
+ global[x] = obj[x];
+ }
+};
+
+
+/**
+ * Adds a dependency from a file to the files it requires.
+ * @param {string} relPath The path to the js file.
+ * @param {Array} provides An array of strings with the names of the objects
+ * this file provides.
+ * @param {Array} requires An array of strings with the names of the objects
+ * this file requires.
+ */
+goog.addDependency = function(relPath, provides, requires) {
+ if (!COMPILED) {
+ var provide, require;
+ var path = relPath.replace(/\\/g, '/');
+ var deps = goog.dependencies_;
+ for (var i = 0; provide = provides[i]; i++) {
+ deps.nameToPath[provide] = path;
+ if (!(path in deps.pathToNames)) {
+ deps.pathToNames[path] = {};
+ }
+ deps.pathToNames[path][provide] = true;
+ }
+ for (var j = 0; require = requires[j]; j++) {
+ if (!(path in deps.requires)) {
+ deps.requires[path] = {};
+ }
+ deps.requires[path][require] = true;
+ }
+ }
+};
+
+
+
+
+// NOTE(nnaze): The debug DOM loader was included in base.js as an orignal
+// way to do "debug-mode" development. The dependency system can sometimes
+// be confusing, as can the debug DOM loader's asyncronous nature.
+//
+// With the DOM loader, a call to goog.require() is not blocking -- the
+// script will not load until some point after the current script. If a
+// namespace is needed at runtime, it needs to be defined in a previous
+// script, or loaded via require() with its registered dependencies.
+// User-defined namespaces may need their own deps file. See http://go/js_deps,
+// http://go/genjsdeps, or, externally, DepsWriter.
+// http://code.google.com/closure/library/docs/depswriter.html
+//
+// Because of legacy clients, the DOM loader can't be easily removed from
+// base.js. Work is being done to make it disableable or replaceable for
+// different environments (DOM-less JavaScript interpreters like Rhino or V8,
+// for example). See bootstrap/ for more information.
+
+
+/**
+ * @define {boolean} Whether to enable the debug loader.
+ *
+ * If enabled, a call to goog.require() will attempt to load the namespace by
+ * appending a script tag to the DOM (if the namespace has been registered).
+ *
+ * If disabled, goog.require() will simply assert that the namespace has been
+ * provided (and depend on the fact that some outside tool correctly ordered
+ * the script).
+ */
+goog.ENABLE_DEBUG_LOADER = true;
+
+
+/**
+ * Implements a system for the dynamic resolution of dependencies
+ * that works in parallel with the BUILD system. Note that all calls
+ * to goog.require will be stripped by the JSCompiler when the
+ * --closure_pass option is used.
+ * @see goog.provide
+ * @param {string} name Namespace to include (as was given in goog.provide())
+ * in the form "goog.package.part".
+ */
+goog.require = function(name) {
+
+ // if the object already exists we do not need do do anything
+ // TODO(arv): If we start to support require based on file name this has
+ // to change
+ // TODO(arv): If we allow goog.foo.* this has to change
+ // TODO(arv): If we implement dynamic load after page load we should probably
+ // not remove this code for the compiled output
+ if (!COMPILED) {
+ if (goog.isProvided_(name)) {
+ return;
+ }
+
+ if (goog.ENABLE_DEBUG_LOADER) {
+ var path = goog.getPathFromDeps_(name);
+ if (path) {
+ goog.included_[path] = true;
+ goog.writeScripts_();
+ return;
+ }
+ }
+
+ var errorMessage = 'goog.require could not find: ' + name;
+ if (goog.global.console) {
+ goog.global.console['error'](errorMessage);
+ }
+
+
+ throw Error(errorMessage);
+
+ }
+};
+
+
+/**
+ * Path for included scripts
+ * @type {string}
+ */
+goog.basePath = '';
+
+
+/**
+ * A hook for overriding the base path.
+ * @type {string|undefined}
+ */
+goog.global.CLOSURE_BASE_PATH;
+
+
+/**
+ * Whether to write out Closure's deps file. By default,
+ * the deps are written.
+ * @type {boolean|undefined}
+ */
+goog.global.CLOSURE_NO_DEPS;
+
+
+/**
+ * A function to import a single script. This is meant to be overridden when
+ * Closure is being run in non-HTML contexts, such as web workers. It's defined
+ * in the global scope so that it can be set before base.js is loaded, which
+ * allows deps.js to be imported properly.
+ *
+ * The function is passed the script source, which is a relative URI. It should
+ * return true if the script was imported, false otherwise.
+ */
+goog.global.CLOSURE_IMPORT_SCRIPT;
+
+
+/**
+ * Null function used for default values of callbacks, etc.
+ * @return {void} Nothing.
+ */
+goog.nullFunction = function() {};
+
+
+/**
+ * The identity function. Returns its first argument.
+ *
+ * @param {*=} opt_returnValue The single value that will be returned.
+ * @param {...*} var_args Optional trailing arguments. These are ignored.
+ * @return {?} The first argument. We can't know the type -- just pass it along
+ * without type.
+ * @deprecated Use goog.functions.identity instead.
+ */
+goog.identityFunction = function(opt_returnValue, var_args) {
+ return opt_returnValue;
+};
+
+
+/**
+ * When defining a class Foo with an abstract method bar(), you can do:
+ *
+ * Foo.prototype.bar = goog.abstractMethod
+ *
+ * Now if a subclass of Foo fails to override bar(), an error
+ * will be thrown when bar() is invoked.
+ *
+ * Note: This does not take the name of the function to override as
+ * an argument because that would make it more difficult to obfuscate
+ * our JavaScript code.
+ *
+ * @type {!Function}
+ * @throws {Error} when invoked to indicate the method should be
+ * overridden.
+ */
+goog.abstractMethod = function() {
+ throw Error('unimplemented abstract method');
+};
+
+
+/**
+ * Adds a {@code getInstance} static method that always return the same instance
+ * object.
+ * @param {!Function} ctor The constructor for the class to add the static
+ * method to.
+ */
+goog.addSingletonGetter = function(ctor) {
+ ctor.getInstance = function() {
+ if (ctor.instance_) {
+ return ctor.instance_;
+ }
+ if (goog.DEBUG) {
+ // NOTE: JSCompiler can't optimize away Array#push.
+ goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
+ }
+ return ctor.instance_ = new ctor;
+ };
+};
+
+
+/**
+ * All singleton classes that have been instantiated, for testing. Don't read
+ * it directly, use the {@code goog.testing.singleton} module. The compiler
+ * removes this variable if unused.
+ * @type {!Array.<!Function>}
+ * @private
+ */
+goog.instantiatedSingletons_ = [];
+
+
+if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
+ /**
+ * Object used to keep track of urls that have already been added. This
+ * record allows the prevention of circular dependencies.
+ * @type {Object}
+ * @private
+ */
+ goog.included_ = {};
+
+
+ /**
+ * This object is used to keep track of dependencies and other data that is
+ * used for loading scripts
+ * @private
+ * @type {Object}
+ */
+ goog.dependencies_ = {
+ pathToNames: {}, // 1 to many
+ nameToPath: {}, // 1 to 1
+ requires: {}, // 1 to many
+ // used when resolving dependencies to prevent us from
+ // visiting the file twice
+ visited: {},
+ written: {} // used to keep track of script files we have written
+ };
+
+
+ /**
+ * Tries to detect whether is in the context of an HTML document.
+ * @return {boolean} True if it looks like HTML document.
+ * @private
+ */
+ goog.inHtmlDocument_ = function() {
+ var doc = goog.global.document;
+ return typeof doc != 'undefined' &&
+ 'write' in doc; // XULDocument misses write.
+ };
+
+
+ /**
+ * Tries to detect the base path of the base.js script that bootstraps Closure
+ * @private
+ */
+ goog.findBasePath_ = function() {
+ if (goog.global.CLOSURE_BASE_PATH) {
+ goog.basePath = goog.global.CLOSURE_BASE_PATH;
+ return;
+ } else if (!goog.inHtmlDocument_()) {
+ return;
+ }
+ var doc = goog.global.document;
+ var scripts = doc.getElementsByTagName('script');
+ // Search backwards since the current script is in almost all cases the one
+ // that has base.js.
+ for (var i = scripts.length - 1; i >= 0; --i) {
+ var src = scripts[i].src;
+ var qmark = src.lastIndexOf('?');
+ var l = qmark == -1 ? src.length : qmark;
+ if (src.substr(l - 7, 7) == 'base.js') {
+ goog.basePath = src.substr(0, l - 7);
+ return;
+ }
+ }
+ };
+
+
+ /**
+ * Imports a script if, and only if, that script hasn't already been imported.
+ * (Must be called at execution time)
+ * @param {string} src Script source.
+ * @private
+ */
+ goog.importScript_ = function(src) {
+ var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
+ goog.writeScriptTag_;
+ if (!goog.dependencies_.written[src] && importScript(src)) {
+ goog.dependencies_.written[src] = true;
+ }
+ };
+
+
+ /**
+ * The default implementation of the import function. Writes a script tag to
+ * import the script.
+ *
+ * @param {string} src The script source.
+ * @return {boolean} True if the script was imported, false otherwise.
+ * @private
+ */
+ goog.writeScriptTag_ = function(src) {
+ if (goog.inHtmlDocument_()) {
+ var doc = goog.global.document;
+ doc.write(
+ '<script type="text/javascript" src="' + src + '"></' + 'script>');
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+
+ /**
+ * Resolves dependencies based on the dependencies added using addDependency
+ * and calls importScript_ in the correct order.
+ * @private
+ */
+ goog.writeScripts_ = function() {
+ // the scripts we need to write this time
+ var scripts = [];
+ var seenScript = {};
+ var deps = goog.dependencies_;
+
+ function visitNode(path) {
+ if (path in deps.written) {
+ return;
+ }
+
+ // we have already visited this one. We can get here if we have cyclic
+ // dependencies
+ if (path in deps.visited) {
+ if (!(path in seenScript)) {
+ seenScript[path] = true;
+ scripts.push(path);
+ }
+ return;
+ }
+
+ deps.visited[path] = true;
+
+ if (path in deps.requires) {
+ for (var requireName in deps.requires[path]) {
+ // If the required name is defined, we assume that it was already
+ // bootstrapped by other means.
+ if (!goog.isProvided_(requireName)) {
+ if (requireName in deps.nameToPath) {
+ visitNode(deps.nameToPath[requireName]);
+ } else {
+ throw Error('Undefined nameToPath for ' + requireName);
+ }
+ }
+ }
+ }
+
+ if (!(path in seenScript)) {
+ seenScript[path] = true;
+ scripts.push(path);
+ }
+ }
+
+ for (var path in goog.included_) {
+ if (!deps.written[path]) {
+ visitNode(path);
+ }
+ }
+
+ for (var i = 0; i < scripts.length; i++) {
+ if (scripts[i]) {
+ goog.importScript_(goog.basePath + scripts[i]);
+ } else {
+ throw Error('Undefined script input');
+ }
+ }
+ };
+
+
+ /**
+ * Looks at the dependency rules and tries to determine the script file that
+ * fulfills a particular rule.
+ * @param {string} rule In the form goog.namespace.Class or project.script.
+ * @return {?string} Url corresponding to the rule, or null.
+ * @private
+ */
+ goog.getPathFromDeps_ = function(rule) {
+ if (rule in goog.dependencies_.nameToPath) {
+ return goog.dependencies_.nameToPath[rule];
+ } else {
+ return null;
+ }
+ };
+
+ goog.findBasePath_();
+
+ // Allow projects to manage the deps files themselves.
+ if (!goog.global.CLOSURE_NO_DEPS) {
+ goog.importScript_(goog.basePath + 'deps.js');
+ }
+}
+
+
+
+//==============================================================================
+// Language Enhancements
+//==============================================================================
+
+
+/**
+ * This is a "fixed" version of the typeof operator. It differs from the typeof
+ * operator in such a way that null returns 'null' and arrays return 'array'.
+ * @param {*} value The value to get the type of.
+ * @return {string} The name of the type.
+ */
+goog.typeOf = function(value) {
+ var s = typeof value;
+ if (s == 'object') {
+ if (value) {
+ // Check these first, so we can avoid calling Object.prototype.toString if
+ // possible.
+ //
+ // IE improperly marshals tyepof across execution contexts, but a
+ // cross-context object will still return false for "instanceof Object".
+ if (value instanceof Array) {
+ return 'array';
+ } else if (value instanceof Object) {
+ return s;
+ }
+
+ // HACK: In order to use an Object prototype method on the arbitrary
+ // value, the compiler requires the value be cast to type Object,
+ // even though the ECMA spec explicitly allows it.
+ var className = Object.prototype.toString.call(
+ /** @type {Object} */ (value));
+ // In Firefox 3.6, attempting to access iframe window objects' length
+ // property throws an NS_ERROR_FAILURE, so we need to special-case it
+ // here.
+ if (className == '[object Window]') {
+ return 'object';
+ }
+
+ // We cannot always use constructor == Array or instanceof Array because
+ // different frames have different Array objects. In IE6, if the iframe
+ // where the array was created is destroyed, the array loses its
+ // prototype. Then dereferencing val.splice here throws an exception, so
+ // we can't use goog.isFunction. Calling typeof directly returns 'unknown'
+ // so that will work. In this case, this function will return false and
+ // most array functions will still work because the array is still
+ // array-like (supports length and []) even though it has lost its
+ // prototype.
+ // Mark Miller noticed that Object.prototype.toString
+ // allows access to the unforgeable [[Class]] property.
+ // 15.2.4.2 Object.prototype.toString ( )
+ // When the toString method is called, the following steps are taken:
+ // 1. Get the [[Class]] property of this object.
+ // 2. Compute a string value by concatenating the three strings
+ // "[object ", Result(1), and "]".
+ // 3. Return Result(2).
+ // and this behavior survives the destruction of the execution context.
+ if ((className == '[object Array]' ||
+ // In IE all non value types are wrapped as objects across window
+ // boundaries (not iframe though) so we have to do object detection
+ // for this edge case
+ typeof value.length == 'number' &&
+ typeof value.splice != 'undefined' &&
+ typeof value.propertyIsEnumerable != 'undefined' &&
+ !value.propertyIsEnumerable('splice')
+
+ )) {
+ return 'array';
+ }
+ // HACK: There is still an array case that fails.
+ // function ArrayImpostor() {}
+ // ArrayImpostor.prototype = [];
+ // var impostor = new ArrayImpostor;
+ // this can be fixed by getting rid of the fast path
+ // (value instanceof Array) and solely relying on
+ // (value && Object.prototype.toString.vall(value) === '[object Array]')
+ // but that would require many more function calls and is not warranted
+ // unless closure code is receiving objects from untrusted sources.
+
+ // IE in cross-window calls does not correctly marshal the function type
+ // (it appears just as an object) so we cannot use just typeof val ==
+ // 'function'. However, if the object has a call property, it is a
+ // function.
+ if ((className == '[object Function]' ||
+ typeof value.call != 'undefined' &&
+ typeof value.propertyIsEnumerable != 'undefined' &&
+ !value.propertyIsEnumerable('call'))) {
+ return 'function';
+ }
+
+
+ } else {
+ return 'null';
+ }
+
+ } else if (s == 'function' && typeof value.call == 'undefined') {
+ // In Safari typeof nodeList returns 'function', and on Firefox
+ // typeof behaves similarly for HTML{Applet,Embed,Object}Elements
+ // and RegExps. We would like to return object for those and we can
+ // detect an invalid function by making sure that the function
+ // object has a call method.
+ return 'object';
+ }
+ return s;
+};
+
+
+/**
+ * Returns true if the specified value is not |undefined|.
+ * WARNING: Do not use this to test if an object has a property. Use the in
+ * operator instead. Additionally, this function assumes that the global
+ * undefined variable has not been redefined.
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is defined.
+ */
+goog.isDef = function(val) {
+ return val !== undefined;
+};
+
+
+/**
+ * Returns true if the specified value is |null|
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is null.
+ */
+goog.isNull = function(val) {
+ return val === null;
+};
+
+
+/**
+ * Returns true if the specified value is defined and not null
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is defined and not null.
+ */
+goog.isDefAndNotNull = function(val) {
+ // Note that undefined == null.
+ return val != null;
+};
+
+
+/**
+ * Returns true if the specified value is an array
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is an array.
+ */
+goog.isArray = function(val) {
+ return goog.typeOf(val) == 'array';
+};
+
+
+/**
+ * Returns true if the object looks like an array. To qualify as array like
+ * the value needs to be either a NodeList or an object with a Number length
+ * property.
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is an array.
+ */
+goog.isArrayLike = function(val) {
+ var type = goog.typeOf(val);
+ return type == 'array' || type == 'object' && typeof val.length == 'number';
+};
+
+
+/**
+ * Returns true if the object looks like a Date. To qualify as Date-like
+ * the value needs to be an object and have a getFullYear() function.
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is a like a Date.
+ */
+goog.isDateLike = function(val) {
+ return goog.isObject(val) && typeof val.getFullYear == 'function';
+};
+
+
+/**
+ * Returns true if the specified value is a string
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is a string.
+ */
+goog.isString = function(val) {
+ return typeof val == 'string';
+};
+
+
+/**
+ * Returns true if the specified value is a boolean
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is boolean.
+ */
+goog.isBoolean = function(val) {
+ return typeof val == 'boolean';
+};
+
+
+/**
+ * Returns true if the specified value is a number
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is a number.
+ */
+goog.isNumber = function(val) {
+ return typeof val == 'number';
+};
+
+
+/**
+ * Returns true if the specified value is a function
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is a function.
+ */
+goog.isFunction = function(val) {
+ return goog.typeOf(val) == 'function';
+};
+
+
+/**
+ * Returns true if the specified value is an object. This includes arrays
+ * and functions.
+ * @param {*} val Variable to test.
+ * @return {boolean} Whether variable is an object.
+ */
+goog.isObject = function(val) {
+ var type = typeof val;
+ return type == 'object' && val != null || type == 'function';
+ // return Object(val) === val also works, but is slower, especially if val is
+ // not an object.
+};
+
+
+/**
+ * Gets a unique ID for an object. This mutates the object so that further
+ * calls with the same object as a parameter returns the same value. The unique
+ * ID is guaranteed to be unique across the current session amongst objects that
+ * are passed into {@code getUid}. There is no guarantee that the ID is unique
+ * or consistent across sessions. It is unsafe to generate unique ID for
+ * function prototypes.
+ *
+ * @param {Object} obj The object to get the unique ID for.
+ * @return {number} The unique ID for the object.
+ */
+goog.getUid = function(obj) {
+ // TODO(arv): Make the type stricter, do not accept null.
+
+ // In Opera window.hasOwnProperty exists but always returns false so we avoid
+ // using it. As a consequence the unique ID generated for BaseClass.prototype
+ // and SubClass.prototype will be the same.
+ return obj[goog.UID_PROPERTY_] ||
+ (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);
+};
+
+
+/**
+ * Removes the unique ID from an object. This is useful if the object was
+ * previously mutated using {@code goog.getUid} in which case the mutation is
+ * undone.
+ * @param {Object} obj The object to remove the unique ID field from.
+ */
+goog.removeUid = function(obj) {
+ // TODO(arv): Make the type stricter, do not accept null.
+
+ // DOM nodes in IE are not instance of Object and throws exception
+ // for delete. Instead we try to use removeAttribute
+ if ('removeAttribute' in obj) {
+ obj.removeAttribute(goog.UID_PROPERTY_);
+ }
+ /** @preserveTry */
+ try {
+ delete obj[goog.UID_PROPERTY_];
+ } catch (ex) {
+ }
+};
+
+
+/**
+ * Name for unique ID property. Initialized in a way to help avoid collisions
+ * with other closure javascript on the same page.
+ * @type {string}
+ * @private
+ */
+goog.UID_PROPERTY_ = 'closure_uid_' +
+ Math.floor(Math.random() * 2147483648).toString(36);
+
+
+/**
+ * Counter for UID.
+ * @type {number}
+ * @private
+ */
+goog.uidCounter_ = 0;
+
+
+/**
+ * Adds a hash code field to an object. The hash code is unique for the
+ * given object.
+ * @param {Object} obj The object to get the hash code for.
+ * @return {number} The hash code for the object.
+ * @deprecated Use goog.getUid instead.
+ */
+goog.getHashCode = goog.getUid;
+
+
+/**
+ * Removes the hash code field from an object.
+ * @param {Object} obj The object to remove the field from.
+ * @deprecated Use goog.removeUid instead.
+ */
+goog.removeHashCode = goog.removeUid;
+
+
+/**
+ * Clones a value. The input may be an Object, Array, or basic type. Objects and
+ * arrays will be cloned recursively.
+ *
+ * WARNINGS:
+ * <code>goog.cloneObject</code> does not detect reference loops. Objects that
+ * refer to themselves will cause infinite recursion.
+ *
+ * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies
+ * UIDs created by <code>getUid</code> into cloned results.
+ *
+ * @param {*} obj The value to clone.
+ * @return {*} A clone of the input value.
+ * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.
+ */
+goog.cloneObject = function(obj) {
+ var type = goog.typeOf(obj);
+ if (type == 'object' || type == 'array') {
+ if (obj.clone) {
+ return obj.clone();
+ }
+ var clone = type == 'array' ? [] : {};
+ for (var key in obj) {
+ clone[key] = goog.cloneObject(obj[key]);
+ }
+ return clone;
+ }
+
+ return obj;
+};
+
+
+/**
+ * A native implementation of goog.bind.
+ * @param {Function} fn A function to partially apply.
+ * @param {Object|undefined} selfObj Specifies the object which |this| should
+ * point to when the function is run.
+ * @param {...*} var_args Additional arguments that are partially
+ * applied to the function.
+ * @return {!Function} A partially-applied form of the function bind() was
+ * invoked as a method of.
+ * @private
+ * @suppress {deprecated} The compiler thinks that Function.prototype.bind
+ * is deprecated because some people have declared a pure-JS version.
+ * Only the pure-JS version is truly deprecated.
+ */
+goog.bindNative_ = function(fn, selfObj, var_args) {
+ return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));
+};
+
+
+/**
+ * A pure-JS implementation of goog.bind.
+ * @param {Function} fn A function to partially apply.
+ * @param {Object|undefined} selfObj Specifies the object which |this| should
+ * point to when the function is run.
+ * @param {...*} var_args Additional arguments that are partially
+ * applied to the function.
+ * @return {!Function} A partially-applied form of the function bind() was
+ * invoked as a method of.
+ * @private
+ */
+goog.bindJs_ = function(fn, selfObj, var_args) {
+ if (!fn) {
+ throw new Error();
+ }
+
+ if (arguments.length > 2) {
+ var boundArgs = Array.prototype.slice.call(arguments, 2);
+ return function() {
+ // Prepend the bound arguments to the current arguments.
+ var newArgs = Array.prototype.slice.call(arguments);
+ Array.prototype.unshift.apply(newArgs, boundArgs);
+ return fn.apply(selfObj, newArgs);
+ };
+
+ } else {
+ return function() {
+ return fn.apply(selfObj, arguments);
+ };
+ }
+};
+
+
+/**
+ * Partially applies this function to a particular 'this object' and zero or
+ * more arguments. The result is a new function with some arguments of the first
+ * function pre-filled and the value of |this| 'pre-specified'.<br><br>
+ *
+ * Remaining arguments specified at call-time are appended to the pre-
+ * specified ones.<br><br>
+ *
+ * Also see: {@link #partial}.<br><br>
+ *
+ * Usage:
+ * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');
+ * barMethBound('arg3', 'arg4');</pre>
+ *
+ * @param {Function} fn A function to partially apply.
+ * @param {Object|undefined} selfObj Specifies the object which |this| should
+ * point to when the function is run.
+ * @param {...*} var_args Additional arguments that are partially
+ * applied to the function.
+ * @return {!Function} A partially-applied form of the function bind() was
+ * invoked as a method of.
+ * @suppress {deprecated} See above.
+ */
+goog.bind = function(fn, selfObj, var_args) {
+ // TODO(nicksantos): narrow the type signature.
+ if (Function.prototype.bind &&
+ // NOTE(nicksantos): Somebody pulled base.js into the default
+ // Chrome extension environment. This means that for Chrome extensions,
+ // they get the implementation of Function.prototype.bind that
+ // calls goog.bind instead of the native one. Even worse, we don't want
+ // to introduce a circular dependency between goog.bind and
+ // Function.prototype.bind, so we have to hack this to make sure it
+ // works correctly.
+ Function.prototype.bind.toString().indexOf('native code') != -1) {
+ goog.bind = goog.bindNative_;
+ } else {
+ goog.bind = goog.bindJs_;
+ }
+ return goog.bind.apply(null, arguments);
+};
+
+
+/**
+ * Like bind(), except that a 'this object' is not required. Useful when the
+ * target function is already bound.
+ *
+ * Usage:
+ * var g = partial(f, arg1, arg2);
+ * g(arg3, arg4);
+ *
+ * @param {Function} fn A function to partially apply.
+ * @param {...*} var_args Additional arguments that are partially
+ * applied to fn.
+ * @return {!Function} A partially-applied form of the function bind() was
+ * invoked as a method of.
+ */
+goog.partial = function(fn, var_args) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return function() {
+ // Prepend the bound arguments to the current arguments.
+ var newArgs = Array.prototype.slice.call(arguments);
+ newArgs.unshift.apply(newArgs, args);
+ return fn.apply(this, newArgs);
+ };
+};
+
+
+/**
+ * Copies all the members of a source object to a target object. This method
+ * does not work on all browsers for all objects that contain keys such as
+ * toString or hasOwnProperty. Use goog.object.extend for this purpose.
+ * @param {Object} target Target.
+ * @param {Object} source Source.
+ */
+goog.mixin = function(target, source) {
+ for (var x in source) {
+ target[x] = source[x];
+ }
+
+ // For IE7 or lower, the for-in-loop does not contain any properties that are
+ // not enumerable on the prototype object (for example, isPrototypeOf from
+ // Object.prototype) but also it will not include 'replace' on objects that
+ // extend String and change 'replace' (not that it is common for anyone to
+ // extend anything except Object).
+};
+
+
+/**
+ * @return {number} An integer value representing the number of milliseconds
+ * between midnight, January 1, 1970 and the current time.
+ */
+goog.now = Date.now || (function() {
+ // Unary plus operator converts its operand to a number which in the case of
+ // a date is done by calling getTime().
+ return +new Date();
+});
+
+
+/**
+ * Evals javascript in the global scope. In IE this uses execScript, other
+ * browsers use goog.global.eval. If goog.global.eval does not evaluate in the
+ * global scope (for example, in Safari), appends a script tag instead.
+ * Throws an exception if neither execScript or eval is defined.
+ * @param {string} script JavaScript string.
+ */
+goog.globalEval = function(script) {
+ if (goog.global.execScript) {
+ goog.global.execScript(script, 'JavaScript');
+ } else if (goog.global.eval) {
+ // Test to see if eval works
+ if (goog.evalWorksForGlobals_ == null) {
+ goog.global.eval('var _et_ = 1;');
+ if (typeof goog.global['_et_'] != 'undefined') {
+ delete goog.global['_et_'];
+ goog.evalWorksForGlobals_ = true;
+ } else {
+ goog.evalWorksForGlobals_ = false;
+ }
+ }
+
+ if (goog.evalWorksForGlobals_) {
+ goog.global.eval(script);
+ } else {
+ var doc = goog.global.document;
+ var scriptElt = doc.createElement('script');
+ scriptElt.type = 'text/javascript';
+ scriptElt.defer = false;
+ // Note(user): can't use .innerHTML since "t('<test>')" will fail and
+ // .text doesn't work in Safari 2. Therefore we append a text node.
+ scriptElt.appendChild(doc.createTextNode(script));
+ doc.body.appendChild(scriptElt);
+ doc.body.removeChild(scriptElt);
+ }
+ } else {
+ throw Error('goog.globalEval not available');
+ }
+};
+
+
+/**
+ * Indicates whether or not we can call 'eval' directly to eval code in the
+ * global scope. Set to a Boolean by the first call to goog.globalEval (which
+ * empirically tests whether eval works for globals). @see goog.globalEval
+ * @type {?boolean}
+ * @private
+ */
+goog.evalWorksForGlobals_ = null;
+
+
+/**
+ * Optional map of CSS class names to obfuscated names used with
+ * goog.getCssName().
+ * @type {Object|undefined}
+ * @private
+ * @see goog.setCssNameMapping
+ */
+goog.cssNameMapping_;
+
+
+/**
+ * Optional obfuscation style for CSS class names. Should be set to either
+ * 'BY_WHOLE' or 'BY_PART' if defined.
+ * @type {string|undefined}
+ * @private
+ * @see goog.setCssNameMapping
+ */
+goog.cssNameMappingStyle_;
+
+
+/**
+ * Handles strings that are intended to be used as CSS class names.
+ *
+ * This function works in tandem with @see goog.setCssNameMapping.
+ *
+ * Without any mapping set, the arguments are simple joined with a
+ * hyphen and passed through unaltered.
+ *
+ * When there is a mapping, there are two possible styles in which
+ * these mappings are used. In the BY_PART style, each part (i.e. in
+ * between hyphens) of the passed in css name is rewritten according
+ * to the map. In the BY_WHOLE style, the full css name is looked up in
+ * the map directly. If a rewrite is not specified by the map, the
+ * compiler will output a warning.
+ *
+ * When the mapping is passed to the compiler, it will replace calls
+ * to goog.getCssName with the strings from the mapping, e.g.
+ * var x = goog.getCssName('foo');
+ * var y = goog.getCssName(this.baseClass, 'active');
+ * becomes:
+ * var x= 'foo';
+ * var y = this.baseClass + '-active';
+ *
+ * If one argument is passed it will be processed, if two are passed
+ * only the modifier will be processed, as it is assumed the first
+ * argument was generated as a result of calling goog.getCssName.
+ *
+ * @param {string} className The class name.
+ * @param {string=} opt_modifier A modifier to be appended to the class name.
+ * @return {string} The class name or the concatenation of the class name and
+ * the modifier.
+ */
+goog.getCssName = function(className, opt_modifier) {
+ var getMapping = function(cssName) {
+ return goog.cssNameMapping_[cssName] || cssName;
+ };
+
+ var renameByParts = function(cssName) {
+ // Remap all the parts individually.
+ var parts = cssName.split('-');
+ var mapped = [];
+ for (var i = 0; i < parts.length; i++) {
+ mapped.push(getMapping(parts[i]));
+ }
+ return mapped.join('-');
+ };
+
+ var rename;
+ if (goog.cssNameMapping_) {
+ rename = goog.cssNameMappingStyle_ == 'BY_WHOLE' ?
+ getMapping : renameByParts;
+ } else {
+ rename = function(a) {
+ return a;
+ };
+ }
+
+ if (opt_modifier) {
+ return className + '-' + rename(opt_modifier);
+ } else {
+ return rename(className);
+ }
+};
+
+
+/**
+ * Sets the map to check when returning a value from goog.getCssName(). Example:
+ * <pre>
+ * goog.setCssNameMapping({
+ * "goog": "a",
+ * "disabled": "b",
+ * });
+ *
+ * var x = goog.getCssName('goog');
+ * // The following evaluates to: "a a-b".
+ * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')
+ * </pre>
+ * When declared as a map of string literals to string literals, the JSCompiler
+ * will replace all calls to goog.getCssName() using the supplied map if the
+ * --closure_pass flag is set.
+ *
+ * @param {!Object} mapping A map of strings to strings where keys are possible
+ * arguments to goog.getCssName() and values are the corresponding values
+ * that should be returned.
+ * @param {string=} opt_style The style of css name mapping. There are two valid
+ * options: 'BY_PART', and 'BY_WHOLE'.
+ * @see goog.getCssName for a description.
+ */
+goog.setCssNameMapping = function(mapping, opt_style) {
+ goog.cssNameMapping_ = mapping;
+ goog.cssNameMappingStyle_ = opt_style;
+};
+
+
+/**
+ * To use CSS renaming in compiled mode, one of the input files should have a
+ * call to goog.setCssNameMapping() with an object literal that the JSCompiler
+ * can extract and use to replace all calls to goog.getCssName(). In uncompiled
+ * mode, JavaScript code should be loaded before this base.js file that declares
+ * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is
+ * to ensure that the mapping is loaded before any calls to goog.getCssName()
+ * are made in uncompiled mode.
+ *
+ * A hook for overriding the CSS name mapping.
+ * @type {Object|undefined}
+ */
+goog.global.CLOSURE_CSS_NAME_MAPPING;
+
+
+if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
+ // This does not call goog.setCssNameMapping() because the JSCompiler
+ // requires that goog.setCssNameMapping() be called with an object literal.
+ goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;
+}
+
+
+/**
+ * Abstract implementation of goog.getMsg for use with localized messages.
+ * @param {string} str Translatable string, places holders in the form {$foo}.
+ * @param {Object=} opt_values Map of place holder name to value.
+ * @return {string} message with placeholders filled.
+ */
+goog.getMsg = function(str, opt_values) {
+ var values = opt_values || {};
+ for (var key in values) {
+ var value = ('' + values[key]).replace(/\$/g, '$$$$');
+ str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), value);
+ }
+ return str;
+};
+
+
+/**
+ * Exposes an unobfuscated global namespace path for the given object.
+ * Note that fields of the exported object *will* be obfuscated,
+ * unless they are exported in turn via this function or
+ * goog.exportProperty
+ *
+ * <p>Also handy for making public items that are defined in anonymous
+ * closures.
+ *
+ * ex. goog.exportSymbol('public.path.Foo', Foo);
+ *
+ * ex. goog.exportSymbol('public.path.Foo.staticFunction',
+ * Foo.staticFunction);
+ * public.path.Foo.staticFunction();
+ *
+ * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
+ * Foo.prototype.myMethod);
+ * new public.path.Foo().myMethod();
+ *
+ * @param {string} publicPath Unobfuscated name to export.
+ * @param {*} object Object the name should point to.
+ * @param {Object=} opt_objectToExportTo The object to add the path to; default
+ * is |goog.global|.
+ */
+goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
+ goog.exportPath_(publicPath, object, opt_objectToExportTo);
+};
+
+
+/**
+ * Exports a property unobfuscated into the object's namespace.
+ * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);
+ * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);
+ * @param {Object} object Object whose static property is being exported.
+ * @param {string} publicName Unobfuscated name to export.
+ * @param {*} symbol Object the name should point to.
+ */
+goog.exportProperty = function(object, publicName, symbol) {
+ object[publicName] = symbol;
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * Usage:
+ * <pre>
+ * function ParentClass(a, b) { }
+ * ParentClass.prototype.foo = function(a) { }
+ *
+ * function ChildClass(a, b, c) {
+ * goog.base(this, a, b);
+ * }
+ * goog.inherits(ChildClass, ParentClass);
+ *
+ * var child = new ChildClass('a', 'b', 'see');
+ * child.foo(); // works
+ * </pre>
+ *
+ * In addition, a superclass' implementation of a method can be invoked
+ * as follows:
+ *
+ * <pre>
+ * ChildClass.prototype.foo = function(a) {
+ * ChildClass.superClass_.foo.call(this, a);
+ * // other code
+ * };
+ * </pre>
+ *
+ * @param {Function} childCtor Child class.
+ * @param {Function} parentCtor Parent class.
+ */
+goog.inherits = function(childCtor, parentCtor) {
+ /** @constructor */
+ function tempCtor() {};
+ tempCtor.prototype = parentCtor.prototype;
+ childCtor.superClass_ = parentCtor.prototype;
+ childCtor.prototype = new tempCtor();
+ /** @override */
+ childCtor.prototype.constructor = childCtor;
+};
+
+
+/**
+ * Call up to the superclass.
+ *
+ * If this is called from a constructor, then this calls the superclass
+ * contructor with arguments 1-N.
+ *
+ * If this is called from a prototype method, then you must pass
+ * the name of the method as the second argument to this function. If
+ * you do not, you will get a runtime error. This calls the superclass'
+ * method with arguments 2-N.
+ *
+ * This function only works if you use goog.inherits to express
+ * inheritance relationships between your classes.
+ *
+ * This function is a compiler primitive. At compile-time, the
+ * compiler will do macro expansion to remove a lot of
+ * the extra overhead that this function introduces. The compiler
+ * will also enforce a lot of the assumptions that this function
+ * makes, and treat it as a compiler error if you break them.
+ *
+ * @param {!Object} me Should always be "this".
+ * @param {*=} opt_methodName The method name if calling a super method.
+ * @param {...*} var_args The rest of the arguments.
+ * @return {*} The return value of the superclass method.
+ */
+goog.base = function(me, opt_methodName, var_args) {
+ var caller = arguments.callee.caller;
+ if (caller.superClass_) {
+ // This is a constructor. Call the superclass constructor.
+ return caller.superClass_.constructor.apply(
+ me, Array.prototype.slice.call(arguments, 1));
+ }
+
+ var args = Array.prototype.slice.call(arguments, 2);
+ var foundCaller = false;
+ for (var ctor = me.constructor;
+ ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {
+ if (ctor.prototype[opt_methodName] === caller) {
+ foundCaller = true;
+ } else if (foundCaller) {
+ return ctor.prototype[opt_methodName].apply(me, args);
+ }
+ }
+
+ // If we did not find the caller in the prototype chain,
+ // then one of two things happened:
+ // 1) The caller is an instance method.
+ // 2) This method was not called by the right caller.
+ if (me[opt_methodName] === caller) {
+ return me.constructor.prototype[opt_methodName].apply(me, args);
+ } else {
+ throw Error(
+ 'goog.base called from a method of one name ' +
+ 'to a method of a different name');
+ }
+};
+
+
+/**
+ * Allow for aliasing within scope functions. This function exists for
+ * uncompiled code - in compiled code the calls will be inlined and the
+ * aliases applied. In uncompiled code the function is simply run since the
+ * aliases as written are valid JavaScript.
+ * @param {function()} fn Function to call. This function can contain aliases
+ * to namespaces (e.g. "var dom = goog.dom") or classes
+ * (e.g. "var Timer = goog.Timer").
+ */
+goog.scope = function(fn) {
+ fn.call(goog.global);
+};
+
+
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Generates out a Closure deps.js file given a list of JavaScript sources.
+
+Paths can be specified as arguments or (more commonly) specifying trees
+with the flags (call with --help for descriptions).
+
+Usage: depswriter.py [path/to/js1.js [path/to/js2.js] ...]
+"""
+
+import logging
+import optparse
+import os
+import posixpath
+import shlex
+import sys
+
+import source
+import treescan
+
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+def MakeDepsFile(source_map):
+ """Make a generated deps file.
+
+ Args:
+ source_map: A dict map of the source path to source.Source object.
+
+ Returns:
+ str, A generated deps file source.
+ """
+
+ # Write in path alphabetical order
+ paths = sorted(source_map.keys())
+
+ lines = []
+
+ for path in paths:
+ js_source = source_map[path]
+
+ # We don't need to add entries that don't provide anything.
+ if js_source.provides:
+ lines.append(_GetDepsLine(path, js_source))
+
+ return ''.join(lines)
+
+
+def _GetDepsLine(path, js_source):
+ """Get a deps.js file string for a source."""
+
+ provides = sorted(js_source.provides)
+ requires = sorted(js_source.requires)
+
+ return 'goog.addDependency(\'%s\', %s, %s);\n' % (path, provides, requires)
+
+
+def _GetOptionsParser():
+ """Get the options parser."""
+
+ parser = optparse.OptionParser(__doc__)
+
+ parser.add_option('--output_file',
+ dest='output_file',
+ action='store',
+ help=('If specified, write output to this path instead of '
+ 'writing to standard output.'))
+ parser.add_option('--root',
+ dest='roots',
+ default=[],
+ action='append',
+ help='A root directory to scan for JS source files. '
+ 'Paths of JS files in generated deps file will be '
+ 'relative to this path. This flag may be specified '
+ 'multiple times.')
+ parser.add_option('--root_with_prefix',
+ dest='roots_with_prefix',
+ default=[],
+ action='append',
+ help='A root directory to scan for JS source files, plus '
+ 'a prefix (if either contains a space, surround with '
+ 'quotes). Paths in generated deps file will be relative '
+ 'to the root, but preceded by the prefix. This flag '
+ 'may be specified multiple times.')
+ parser.add_option('--path_with_depspath',
+ dest='paths_with_depspath',
+ default=[],
+ action='append',
+ help='A path to a source file and an alternate path to '
+ 'the file in the generated deps file (if either contains '
+ 'a space, surround with whitespace). This flag may be '
+ 'specified multiple times.')
+ return parser
+
+
+def _NormalizePathSeparators(path):
+ """Replaces OS-specific path separators with POSIX-style slashes.
+
+ Args:
+ path: str, A file path.
+
+ Returns:
+ str, The path with any OS-specific path separators (such as backslash on
+ Windows) replaced with URL-compatible forward slashes. A no-op on systems
+ that use POSIX paths.
+ """
+ return path.replace(os.sep, posixpath.sep)
+
+
+def _GetRelativePathToSourceDict(root, prefix=''):
+ """Scans a top root directory for .js sources.
+
+ Args:
+ root: str, Root directory.
+ prefix: str, Prefix for returned paths.
+
+ Returns:
+ dict, A map of relative paths (with prefix, if given), to source.Source
+ objects.
+ """
+ # Remember and restore the cwd when we're done. We work from the root so
+ # that paths are relative from the root.
+ start_wd = os.getcwd()
+ os.chdir(root)
+
+ path_to_source = {}
+ for path in treescan.ScanTreeForJsFiles('.'):
+ prefixed_path = _NormalizePathSeparators(os.path.join(prefix, path))
+ path_to_source[prefixed_path] = source.Source(source.GetFileContents(path))
+
+ os.chdir(start_wd)
+
+ return path_to_source
+
+
+def _GetPair(s):
+ """Return a string as a shell-parsed tuple. Two values expected."""
+ try:
+ # shlex uses '\' as an escape character, so they must be escaped.
+ s = s.replace('\\', '\\\\')
+ first, second = shlex.split(s)
+ return (first, second)
+ except:
+ raise Exception('Unable to parse input line as a pair: %s' % s)
+
+
+def main():
+ """CLI frontend to MakeDepsFile."""
+ logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
+ level=logging.INFO)
+ options, args = _GetOptionsParser().parse_args()
+
+ path_to_source = {}
+
+ # Roots without prefixes
+ for root in options.roots:
+ path_to_source.update(_GetRelativePathToSourceDict(root))
+
+ # Roots with prefixes
+ for root_and_prefix in options.roots_with_prefix:
+ root, prefix = _GetPair(root_and_prefix)
+ path_to_source.update(_GetRelativePathToSourceDict(root, prefix=prefix))
+
+ # Source paths
+ for path in args:
+ path_to_source[path] = source.Source(source.GetFileContents(path))
+
+ # Source paths with alternate deps paths
+ for path_with_depspath in options.paths_with_depspath:
+ srcpath, depspath = _GetPair(path_with_depspath)
+ path_to_source[depspath] = source.Source(source.GetFileContents(srcpath))
+
+ # Make our output pipe.
+ if options.output_file:
+ out = open(options.output_file, 'w')
+ else:
+ out = sys.stdout
+
+ out.write('// This file was autogenerated by %s.\n' % sys.argv[0])
+ out.write('// Please do not edit.\n')
+
+ out.write(MakeDepsFile(path_to_source))
+
+
+if __name__ == '__main__':
+ main()
--- /dev/null
+# Copyright 2009 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Scans a source JS file for its provided and required namespaces.
+
+Simple class to scan a JavaScript file and express its dependencies.
+"""
+
+__author__ = 'nnaze@google.com'
+
+
+import re
+
+_BASE_REGEX_STRING = '^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
+_PROVIDE_REGEX = re.compile(_BASE_REGEX_STRING % 'provide')
+_REQUIRES_REGEX = re.compile(_BASE_REGEX_STRING % 'require')
+
+# This line identifies base.js and should match the line in that file.
+_GOOG_BASE_LINE = (
+ 'var goog = goog || {}; // Identifies this file as the Closure base.')
+
+
+class Source(object):
+ """Scans a JavaScript source for its provided and required namespaces."""
+
+ # Matches a "/* ... */" comment.
+ # Note: We can't definitively distinguish a "/*" in a string literal without a
+ # state machine tokenizer. We'll assume that a line starting with whitespace
+ # and "/*" is a comment.
+ _COMMENT_REGEX = re.compile(
+ r"""
+ ^\s* # Start of a new line and whitespace
+ /\* # Opening "/*"
+ .*? # Non greedy match of any characters (including newlines)
+ \*/ # Closing "*/""",
+ re.MULTILINE | re.DOTALL | re.VERBOSE)
+
+ def __init__(self, source):
+ """Initialize a source.
+
+ Args:
+ source: str, The JavaScript source.
+ """
+
+ self.provides = set()
+ self.requires = set()
+
+ self._source = source
+ self._ScanSource()
+
+ def __str__(self):
+ return 'Source %s' % self._path
+
+ def GetSource(self):
+ """Get the source as a string."""
+ return self._source
+
+ @classmethod
+ def _StripComments(cls, source):
+ return cls._COMMENT_REGEX.sub('', source)
+
+ def _ScanSource(self):
+ """Fill in provides and requires by scanning the source."""
+
+ source = self._StripComments(self.GetSource())
+
+ source_lines = source.splitlines()
+ for line in source_lines:
+ match = _PROVIDE_REGEX.match(line)
+ if match:
+ self.provides.add(match.group(1))
+ match = _REQUIRES_REGEX.match(line)
+ if match:
+ self.requires.add(match.group(1))
+
+ # Closure's base file implicitly provides 'goog'.
+ for line in source_lines:
+ if line == _GOOG_BASE_LINE:
+ if len(self.provides) or len(self.requires):
+ raise Exception(
+ 'Base files should not provide or require namespaces.')
+ self.provides.add('goog')
+
+
+def GetFileContents(path):
+ """Get a file's contents as a string.
+
+ Args:
+ path: str, Path to file.
+
+ Returns:
+ str, Contents of file.
+
+ Raises:
+ IOError: An error occurred opening or reading the file.
+
+ """
+ fileobj = open(path)
+ try:
+ return fileobj.read()
+ finally:
+ fileobj.close()
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright 2010 The Closure Library Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Shared utility functions for scanning directory trees."""
+
+import os
+import re
+
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+# Matches a .js file path.
+_JS_FILE_REGEX = re.compile(r'^.+\.js$')
+
+
+def ScanTreeForJsFiles(root):
+ """Scans a directory tree for JavaScript files.
+
+ Args:
+ root: str, Path to a root directory.
+
+ Returns:
+ An iterable of paths to JS files, relative to cwd.
+ """
+ return ScanTree(root, path_filter=_JS_FILE_REGEX)
+
+
+def ScanTree(root, path_filter=None, ignore_hidden=True):
+ """Scans a directory tree for files.
+
+ Args:
+ root: str, Path to a root directory.
+ path_filter: A regular expression filter. If set, only paths matching
+ the path_filter are returned.
+ ignore_hidden: If True, do not follow or return hidden directories or files
+ (those starting with a '.' character).
+
+ Yields:
+ A string path to files, relative to cwd.
+ """
+
+ def OnError(os_error):
+ raise os_error
+
+ for dirpath, dirnames, filenames in os.walk(root, onerror=OnError):
+ # os.walk allows us to modify dirnames to prevent decent into particular
+ # directories. Avoid hidden directories.
+ for dirname in dirnames:
+ if ignore_hidden and dirname.startswith('.'):
+ dirnames.remove(dirname)
+
+ for filename in filenames:
+
+ # nothing that starts with '.'
+ if ignore_hidden and filename.startswith('.'):
+ continue
+
+ fullpath = os.path.join(dirpath, filename)
+
+ if path_filter and not path_filter.match(fullpath):
+ continue
+
+ yield os.path.normpath(fullpath)
--- /dev/null
+var console = {};
+
+console.log = function() {
+ return void 0;
+}
+++ /dev/null
-(function(global) {
- var FlappDict = function() {
- this.characters = {};
- };
- FlappDict.prototype = {
- set: function(id, tag) {
- this.characters[tag.id] = tag;
- },
- get: function(id) {
- return this.characters[id];
- }
- };
- global.FlappDict = FlappDict;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappDisplay = function() {
- this.objs = {};
- this.places = {};
- };
- FlappDisplay.prototype = {
- set: function(depth, obj, place) {
- if (obj) {
- this.objs[depth] = obj;
- if (place.matrix) {
- obj.matrix = place.matrix;
- }
- if (place.colorTransform) {
- obj.colorTransform = place.colorTransform;
- }
- }
- this.places[depth] = place;
- },
- getObj: function(depth) {
- return this.objs[depth];
- },
- getPlace: function(depth) {
- return this.places[depth];
- },
- del: function(depth) {
- delete this.objs[depth];
- delete this.places[depth];
- },
- descSortedDepth: function() {
- var depthList = new Array(this.objs.length);
- var keys = Object.keys(this.objs);
- return keys.sort(
- function(a,b) { return (a>b)?-1:((a<b)?1:0); }
- );
- }
- };
- global.FlappDisplay = FlappDisplay;
-})(this);
+++ /dev/null
-/*
- input bit stream reader
- (c) 2012/11/17- yoya@awm.jp
-*/
-
-(function(global) {
- var FlappIBit = function() {
- this.byteOffset = 0;
- this.bitOffset = 0;
- this.dataAllocLen = 0;
- this.data = null;
- this.dataLen = 0;
- };
- FlappIBit.prototype = {
- input: function(data) {
- if (typeof data === 'string') {
- this.inputStr(data);
- } else {
- this.inputArray(data);
- }
- },
- inputStr: function(data) {
- var dataLen = data.length;
- if (this.dataAllocLen < dataLen) {
- var oldData = this.data;
- this.data = new Uint8Array(dataLen);
- for (var i = 0 , l = this.dataLen; i < l ; i++) {
- this.data[i] = data.charCodeAt(i);
- }
- this.dataAllocLen = dataLen;
- }
- for (var i = this.dataLen ; i < dataLen ; i++) {
- this.data[i] = data.charCodeAt(i);
- }
- this.dataLen = dataLen;
- },
- inputArray: function(data) {
- this.data = data;
- this.dataAllocLen = this.dataLen = data.length;
- },
- len: function() { // data lengh
- return this.dataLen;
- },
- hasNext: function(len) {
- var nextOffset = this.byteOffset + (this.bitOffset?1:0) + len;
- return (nextOffset < this.dataLen)?true:false;
- },
- getBytePos: function() { // get byte position
- return this.byteOffset;
- },
- setPos: function(byteOffset, bitOffset) { // set byte position
- this.byteOffset = byteOffset;
- this.bitOffset = bitOffset;
- },
- seek: function(byteDelta, bitDelta) { // relative seek
- this.byteOffset += byteDelta;
- this.bitOffset += bitDelta;
- if (this.bitOffset < 0) {
- do {
- this.byteOffset --;
- this.bitOffset += 8;
- } while (this.bitOffset < 0);
- } else if (this.bitOffset > 7) {
- do {
- this.byteOffset ++;
- this.bitOffset -= 8;
- } while (this.bitOffset > 7);
- }
- },
- a: function() { // skip bit
- if (this.bitOffset) {
- this.byteOffset++;
- this.bitOffset = 0;
- }
- },
- b: function() { // bit
- var value = (this.data[this.byteOffset] >>> (7 - this.bitOffset++)) & 1;
- if (this.bitOffset === 8) {
- this.byteOffset++;
- this.bitOffset = 0;
- }
- return value;
- },
- ub: function(len) { // unsigned bits
- var value = 0;
- while (len--) {
- value = (value << 1) | this.b();
- }
- return value;
- },
- sb: function(len) { // signed bits
- var value = 0;
- if (len === 0) return 0; // XXX
- var msb = this.b();
- if (msb) {
- var orig_len = len;
- }
- while (--len) {
- value = (value << 1) | this.b();
- }
- if (msb) {
- return value - (1 << (orig_len - 1));
- }
- return value;
- },
- si8: function() { // snsigned 8-bit integer
- value = this.ui8();
- return (value & 0x80)?(value - 0x100):value;
- },
- si16: function() { // snsigned 16-bit integer
- value = this.ui16();
- return (value & 0x8000)?(value - 0x10000):value;
-
- },
- si32: function() { // snsigned 32-bit integer
- value = this.ui32();
- return (value & 0x80000000)?(value - 0x100000000):value;
- },
- ui8: function() { // unsigned 8-bit integer
- this.a();
- return this.data[this.byteOffset++];
- },
- ui16: function() { // unsigned 16-bit integer
- this.a();
- return this.data[this.byteOffset++] |
- (this.data[this.byteOffset++] << 8);
- },
- ui32: function() { // unsigned 32-bit integer
- this.a();
- return this.data[this.byteOffset++] |
- (this.data[this.byteOffset++] << 8) |
- (this.data[this.byteOffset++] << 16) |
- (this.data[this.byteOffset++] << 24);
- },
- sub: function(len) {
- this.a();
- var data = this.data.subarray(this.byteOffset, this.byteOffset + len);
- this.byteOffset += len;
- return data;
- },
- strN: function(len) {
- this.a();
- var data = this.data;
- var str = [];
- for (var i = this.byteOffset, l = this.byteOffset + len ; i < len ; i++) {
- str.push(String.fromCharCode(data[i]))
- }
- this.byteOffset += len;
-// return new FlappUTF8().fromSJISArray(data);
- return str.join('');
- },
- str: function(len) {
- this.a();
- var byteOffset = this.byteOffset;
- var dataLen = this.dataLen;
- for (var i = byteOffset ; i < dataLen ; i++) {
- if (this.data[i] === 0) {
- data = this.strN(i - byteOffset);
- this.byteOffset++; // skip "\0"
- return data;
- }
- }
- return this.strN(i - byteOffset);
- }
-
- };
- global.FlappIBit = FlappIBit;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappLoader = function(flapp) {
- this.flapp = flapp;
- }
- FlappLoader.prototype = {
- fromURL: function(url, dict, movieClip) {
- console.debug("FlappLoader.prototype.fromURL("+url+",flapp,dict,movieClip");
- var xhr = new XMLHttpRequest();
- var ibit = new FlappIBit();
- var loader = this;
- this.header = null;
- xhr.onreadystatechange = function() {
- if (xhr.readyState > 1) {
- if (xhr.status == 200) {
- if (xhr.responseText) {
- ibit.input(xhr.responseText);
- loader.parse(ibit, dict, movieClip);
- }
- }
- }
- }
- xhr.open('GET', url);
- // xhr.responseType = 'arraybuffer';
- xhr.overrideMimeType('text/plain; charset=x-user-defined');
- xhr.send(null);
- },
- parse: function(ibit, dict, movieClip) {
- // console.debug("FlappLoader.prototype.parse");
- if (ibit.len() < 20) { // 20 is minumum size for swf header, maybe.
- return ;
- }
- if (this.header === null) {
- this.header = FlappSWFHeader.load(ibit);
- console.debug(this.header);
- flapp.setHeader(this.header);
- }
- var jpegTables = null;
- while (ibit.a(), ibit.hasNext(2)) {
- var headPos = ibit.getBytePos();
- var tag_and_length = ibit.ui16(); // tag and length
- var code = tag_and_length >>> 6;
- var length = tag_and_length & 0x3f;
- if (length === 0x3f) {
- if (ibit.hasNext(4) === false) {
- ibit.setPos(headPos, 0);
- break;
- }
- length = ibit.ui32();
- }
- if (ibit.hasNext(length) === false) {
- ibit.setPos(headPos, 0);
- break;
- }
- var startOfContent = ibit.getBytePos();
- var tag = new FlappSWFTag.load(code, length, ibit);
-// console.debug(tag);
- switch (code) {
- case 1: // ShowFrame
- movieClip.appendControlTag(tag);
- break;
- case 2: // DefineShape
- case 22: // DefineShape2
- case 32: // DefineShape3
- dict.set(tag.id, tag);
- break;
- case 6: // DefineBits(JPEG)
- var jpeg = FlappBitmap.toJpeg(tag.jpegData, jpegTables);
- var image = new Image();
- image.src = "data:image/jpeg;base64,"+btoa(jpeg);
- tag.image = image;
- dict.set(tag.id, tag);
- break;
- case 8: // JPEGTables
- jpegTables = tag;
- break;
- case 9: // SetBackgroundColor
- // set canvas background
- break;
- case 12: // DoAction
- movieClip.appendControlTag(tag);
- break;
- case 26: // PlaceObject2
- movieClip.appendControlTag(tag);
- break;
- default:
- console.warn("Unknown swf tag code:"+code);
- break;
- }
- ibit.setPos(startOfContent + length, 0);
- }
- }
- };
- global.FlappLoader = FlappLoader;
-})(this);
+++ /dev/null
-(function(global) {
- var Flapp = function(url, canvas_id) {
- console.debug("Flapp("+url+","+canvas_id+")");
- this.url = url;
- this.canvas_id = canvas_id;
- this.canvas = document.getElementById(canvas_id);
- global.flapp = this; // debug
- this.header = null
-// this.frameTick = 1000 / 10; // default 0.1[sec]
- this.frameTick = 1000; // default
- };
- Flapp.prototype = {
- play: function() {
- console.debug("Flapp.prototype.play");
- var flapp = this;
- var loader = new FlappLoader(flapp); // file loader
- this.dict = new FlappDict(); // content dictionary
- this.movieClip = new FlappMovieClip(); // root MC
- loader.fromURL(this.url, this.dict, this.movieClip);
- this.canvas = new FlappCanvas(this.canvas);
- this.run(this.dict, this.movieClip, this.canvas);
- },
- setHeader: function(header) {
-// this.frameTick = 1000 / header.framerate;
- this.frameTick = 1000;
- this.movieClip.totalframes = header.framecount;
- },
- run: function(dict, movieClip, canvas) {
- console.debug("Flapp::run");
- var flapp = this;
- this.canvas = canvas;
- this.tick(flapp, this.dict, this.movieClip);
- },
- tick: function(flapp, dict, movieClip) {
- console.debug("Flapp::tick "+movieClip.currentFrame);
- setTimeout(flapp.tick, flapp.frameTick, flapp, dict, movieClip);
- if (movieClip.control(dict)) {
- movieClip.action();
- movieClip.render(flapp.canvas);
- movieClip.increment();
- }
- }
- };
- global.Flapp = Flapp;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappMemory = function() {
- ;
- };
- FlappMemory.prototype = {
- add: function(key, content) {
- ;
- },
- del: function(key, content) {
- ;
- }
- };
- global.FlappMemory = FlappMemory;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappMovieClip = function(parentMovieClip, name, matrix, colorTransform) {
- this.OBJECT_TYPE = 2; // 1:Shape, 2: MovieClip
- this.parentMovieClip = parentMovieClip?parentMovieCli:null;
- this.rootMovieClip = parentMovieClip?parentMovieClip.rootMovieClip:this;
- this.name = name?name:'anonymous';
- this.matrix = matrix;
- this.colorTransform = colorTransform;
- this.childMovieClips = {}; // name => movieClip
- this.childMovieClips_seqnum = 1; // for name movieClip
- this.clearControlTags();
- //
- this.prevShowFramePos = 0;
- //
- canvas = document.createElement('canvas');
- canvas.width = 240; // XXX
- canvas.height = 240; // XXX
- this.canvas = canvas;
- this.canvasDirty = false; // dirtyFlag
- //
- this.displayList = new FlappDisplay();
- //
- this.totalframes = 0;
- this.currentFrame = 0;
- this.playing = true;
- // this.loop = true;
- this.loop = false;
- var actionVarriableTable = {};
- var actionVarriablOrigKeys = {};
- };
- FlappMovieClip.prototype = {
- clearControlTags: function(controlTag) {
- this.controlTagsList = [[]]; //
- this.actionTagsList = [[]];
- this.labelMap = {}; // label => frameNum
- this.framesLoaded = 0;
- },
- appendControlTag: function(controlTag) {
- // console.debug("FlappMovieClip::appendControlTag");
- if (controlTag.code === 12) { // DoAction
- this.actionTagsList[this.framesLoaded].push(controlTag);
- return ;
- }
- this.controlTagsList[this.framesLoaded].push(controlTag);
- if (controlTag.code === 1) { // ShowFrame
- this.controlTagsList.push([]);
- this.actionTagsList.push([]);
- this.framesLoaded++;
- } else if (controlTag.code === 43) { // FrameLabel
- this.labelMap[controlTag.name] = this.framesLoaded;
- }
- },
- setControlTags: function(controlTags) {
- this.clearControlTags();
- for (var i = 0, l = controlTags.length ; i < l ; i++) {
- this.appendControlTag(controlTags[i]);
- }
- },
- addChildMovieClip: function(name, movieClip) {
- this.childMovieClips[name] = movieClip;
- },
- deleteChildMovieClip: function(name) {
- delete this.childMovieClips[name];
- },
- control: function(dict) {
- if (this.totalframes === 0) { // imcomplete
- return false;
- }
- console.debug("FlappMovieClip::control");
- if (this.framesLoaderd < this.totalframes) { // imcomplete
- if (this.currentFrame < this.framesLoaderd) {
- return false; // idle
- }
- }
- for (var mc in this.childMovieClips) {
- this.childMovieClips[mc].control(dict);
- }
- if (this.playing) {
- this.controlThis(dict);
- }
- return true;
- },
- controlThis: function(dict) {
- console.debug("FlappMovieClip::controlThis");
- var tag, i, l;
- var defineTag;
- if ((this.currentFrame < 0 ) || (this.totalframes <= this.currentFrame)) {
- this.currentFrame = 0;
- }
- var controlTags = this.controlTagsList[this.currentFrame];
-
- for (i = 0, l = controlTags.length ; i < l ; i++) {
- tag = controlTags[i];
- switch (tag.code) {
- case 1: // ShowFrame
- break;
- case 26: // PlaceObject2
- // set display List;
- var obj = null;
- if (tag.move) {
- this.displayList.set(tag.depth, obj, tag);
- } else {
- defineTag = dict.get(tag.id);
- console.log(tag);
- if (defineTag.code === 39) { // DefineSprite
- var name = tag.name;
- if (name === null) {
- name = "instance"+this.childMovieClips_seqnum;
- defineTag.name = name;
- this.childMovieClips_seqnum++;
- }
- var obj = FlappMovieClip(this, name, tag.matrix, tag.colorTransform);
- obj.setControlTags(defineTag.controlTags);
- this.addChildMovieClip(name, obj);
- } else if (defineTag.code === 2) { // DefineShape
- var obj = new FlappShape(name, tag.matrix, tag.colorTransform);
- console.log(obj);
- obj.loadShapeTag(defineTag);
- }
- this.displayList.set(tag.depth, obj, tag);
- break;
- }
- }
- }
- },
- action: function() {
- for (var mc in this.childMovieClips) {
- this.childMovieClips[mc].action();
- }
- if (this.playing) {
- this.actionThis();
- }
-
- },
- actionThis: function() {
- var actionTags = this.actionTagsList[this.currentFrame];
- var l = actionTags.length;
- console.debug("FlappMovieClip::actionThis: actionTags.length:"+l);
- for (var i = 0 ; i < l ; i++) {
- var tag = actionTags[i];
- var movieClip = this;
- FlappAction.exec(tag, movieClip, this.rootMovieClip);
- }
- },
- increment: function() {
- for (var mc in this.childMovieClips) {
- this.childMovieClips[mc].increment();
- }
- if (this.playing) {
- this.incrementThis();
- }
- },
- incrementThis: function() {
- console.debug("FlappMovieClip::incrementThis: "+this.currentFrame);
- this.currentFrame++;
- if (this.totalframes <= this.currentFrame) {
- if (this.loop) {
- this.currentFrame = 0; // play
- } else {
- this.playing = false;
- }
- }
- if (this.totalframes === 1) {
- this.playing = false;
- }
- },
- render: function(canvas) {
- var depthList = this.displayList.descSortedDepth();
- for (var i = 0, l = depthList.length ; i < l ; i++) {
- var depth = depthList[i];
- var obj = this.displayList.getObj(depth);
- if (obj.OBJECT_TYPE === 2) { // MovieClip
- obj.render(this.canvas);
- } else if ((obj.OBJECT_TYPE === 2) && (this.playing == true)) {
- obj.render(this.canvas);
- }
- }
- },
- setVariable: function(key, value) {
- var lcKey = key.toLowerCase();
- actionVarriableTable[lcKey] = value;
- actionVarriablOrigKeys[lcKey] = key;
- },
- getVariable: function(key) {
- var lcKey = key.toLowerCase();
- if (lcKey in actionVarriableTable) {
- return actionVarriableTable[lcKey];
- }
- return null;
- },
- gotoFrame: function(frameNum) {
- console.debug("FlappMovieClip::gotoFrame"+frameNum);
- this.currentFrame = frameNum;
- },
- gotoLabel: function(frameLabel) {
- frameNum = labelMap[frameLabel];
- console.debug("FlappMovieClip::gotoFrame"+frameLabel+"=>"+frameNum);
- this.currentFrame = frameNum;
- },
- play: function() {
- this.playing = true;
- },
- stop: function() {
- this.playing = false;
- },
- destroy: function() { // destructor
- for (name in this.childMovieClips) {
- this.childMovieClips[name].destroy();
- }
- this.parentMovieClip = null;
- this.rootMovieClip = null;
- this.controlTagsList = null;
- this.actionTagsList = null;
- this.labelMap = null;
- this.canvas = null;
- this.displayList = null;
- }
- };
- global.FlappMovieClip = FlappMovieClip;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappShape = function(name, matrix, colorTransform) {
- this.OBJECT_TYPE = 1; // 1:Shape, 2:MovieClip
- this.canvas = document.createElement('canvas');
- canvas.width = 240; // XXX
- canvas.height = 240; // XXX
- this.renderCode = "";
- };
- FlappShape.prototype = {
- loadShapeTag: function(shape) {
- ;
- },
- render: function(canvas) {
- ;
- }
- };
- FlappShape.shapetoRenderCode = function(shapeTag) {
- ;
- }
- global.FlappShape = FlappShape;
-})(this);
--- /dev/null
+goog.provide('FlappAction');
+goog.require('FlappIBit');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappAction = function() {
+ this.actionRecord = null;
+};
+
+FlappAction.exec = function(tag, movieClip, rootMovieClip) {
+ console.debug("FlappAction.exec");
+ var actionsBit = new FlappIBit();
+ actionsBit.input(tag.actions);
+ var code = 0;
+ var stack = [];
+ while (code = actionsBit.ui8()) {
+ if (code < 0x80) {
+ switch (code) {
+ case 0x06: // Play
+ movieClip.play();
+ break;
+ case 0x07: // Stop
+ movieClip.stop();
+ break;
+ case 0x1d: // SetVariables
+ movieClip.setVariable(stack.pop(), stack.pop());
+ break;
+ default:
+ console.debug("FlappActiom: not implemented yet. code=0x%02x", code);
+ break;
+ }
+ } else {
+ var actionLength = actionsBit.input(tag.actions);
+ var nextActionOffset = actionsBit.getBytePos() + actionLength;
+ switch (code) {
+ case 0x81: // GotoFrame
+ movieClip.gotoFrame(actionsBit.si16());
+ break;
+ case 0x83: // GetURL
+ //
+ break;
+ case 0x8c: // GoToLabel
+ movieClip.gotoLabel(actionsBit.strN(actionLength));
+ break;
+ //case 0x96: // Push
+ default:
+ console.debug("FlappActiom: not implemented yet. code=0x%02x", code);
+ break;
+ }
+ actionsBit.setPos(nextActionOffset, 0);
+ }
+ }
+};
+
+});
--- /dev/null
+goog.provide('FlappBitmap');
+goog.require('FlappIBit');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappBitmap = function() {
+ ;
+};
+
+FlappBitmap.jpegChunkOffsets = function(jpegData) {
+ var offsetTable = {};
+ var ibit = new FlappIBit();
+ while (ibit.hasNext(2)) {
+ var marker = ibit.ui16be();
+ var offset = ibit.getBytePos();
+ var length;
+ switch (marker) {
+ case 0xFFD8: // SOI
+ case 0xFFD9: // EOI
+ break;
+ case 0xFFDA: // SOS + [RST] + EOI
+ length = ibit.len() - offset;
+ offsetTable[marker] = [offset, length]
+ break;
+ default:
+ length = ibit.ui16be() + 2;
+ offsetTable[marker] = [offset, length]
+
+ break;
+ }
+ }
+ return offsetTable;
+};
+
+FlappBitmap.toJpeg = function(swfJpeg, jpegTables) {
+ var offsetTable = FlappBitmap.jpegChunkOffsets(swfJpeg);
+ var hasDQT = (0xFFDB in offsetTable);
+ if (hasDQT === false) {
+ var offsetTable2 = FlappBitmap.jpegChunkOffsets(jpegTables);
+ }
+ var jpegArray = [0xFF, 0xD8]; // SOI
+ // APP0, SOF0, DQT, DHT, SOS
+ var jpegOrder = [0xFFE0, 0xFFC0, 0xFFDB, 0xFFC4, 0xFFDA];
+ for (var i = 0, l = jpegOrder; i < l ; i++) {
+ var marker = jpegOrder[i];
+ var swfJpegOffset = (marker in offsetTable);
+ if (swfJpegOffset) {
+ var entry = offsetTable[marker];
+ } else {
+ var entry = offsetTable2[marker];
+ }
+ var offset = entry[0];
+ var enfoffset = offset + entry[1];
+ for (var j = offset; j < enfoffset ; j++) {
+ if (swfJpegOffset) {
+ jpegArray.join(swfJpeg[j]);
+ } else {
+ jpegArray.join(jpegTables[j]);
+ }
+ }
+ }
+ return FlappString.ArrayToString(jpegArray);
+};
+
+FlappBitmap.toPng = function(lossless) {
+ ;
+};
+
+});
--- /dev/null
+goog.provide('FlappCanvas');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappCanvas = function(canvas) {
+ this.canvas = canvas;
+ this.ctx = canvas.getContext('2d');
+};
+
+});
--- /dev/null
+goog.provide('FlappDict');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappDict = function() {
+ this.characters = {};
+};
+
+FlappDict.prototype = {
+ set: function(id, tag) {
+ this.characters[tag.id] = tag;
+ },
+ get: function(id) {
+ return this.characters[id];
+ }
+};
+
+});
--- /dev/null
+goog.provide('FlappDisplay');
+
+goog.scope(function () {
+
+/**
+ * @constructor
+ */
+FlappDisplay = function() {
+ this.objs = {};
+ this.places = {};
+};
+
+FlappDisplay.prototype = {
+ set: function(depth, obj, place) {
+ if (obj) {
+ this.objs[depth] = obj;
+ if (place.matrix) {
+ obj.matrix = place.matrix;
+ }
+ if (place.colorTransform) {
+ obj.colorTransform = place.colorTransform;
+ }
+ }
+ this.places[depth] = place;
+ },
+ getObj: function(depth) {
+ return this.objs[depth];
+ },
+ getPlace: function(depth) {
+ return this.places[depth];
+ },
+ del: function(depth) {
+ delete this.objs[depth];
+ delete this.places[depth];
+ },
+ descSortedDepth: function() {
+ var depthList = new Array(this.objs.length);
+ var keys = Object.keys(this.objs);
+ return keys.sort(
+ function(a,b) { return (a>b)?-1:((a<b)?1:0); }
+ );
+ }
+};
+
+});
-(function(global) {
- var FlappEvent = function() {
+goog.provide('FlappEvent');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappEvent = function() {
this.eventMap = {};
};
FlappEvent.prototype = {
// addListner to Obejct.
}
};
- global.FlappEvent = FlappEvent;
-})(this);
+
+});
--- /dev/null
+/*
+ input bit stream reader
+ (c) 2012/11/17- yoya@awm.jp
+*/
+goog.provide('FlappIBit');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappIBit = function() {
+ this.byteOffset = 0;
+ this.bitOffset = 0;
+ this.dataAllocLen = 0;
+ this.data = null;
+ this.dataLen = 0;
+};
+
+FlappIBit.prototype = {
+ input: function(data) {
+ if (typeof data === 'string') {
+ this.inputStr(data);
+ } else {
+ this.inputArray(data);
+ }
+ },
+ inputStr: function(data) {
+ var dataLen = data.length;
+ if (this.dataAllocLen < dataLen) {
+ var oldData = this.data;
+ this.data = new Uint8Array(dataLen);
+ for (var i = 0 , l = this.dataLen; i < l ; i++) {
+ this.data[i] = data.charCodeAt(i);
+ }
+ this.dataAllocLen = dataLen;
+ }
+ for (var i = this.dataLen ; i < dataLen ; i++) {
+ this.data[i] = data.charCodeAt(i);
+ }
+ this.dataLen = dataLen;
+ },
+ inputArray: function(data) {
+ this.data = data;
+ this.dataAllocLen = this.dataLen = data.length;
+ },
+ len: function() { // data lengh
+ return this.dataLen;
+ },
+ hasNext: function(len) {
+ var nextOffset = this.byteOffset + (this.bitOffset?1:0) + len;
+ return (nextOffset < this.dataLen);
+ },
+ getBytePos: function() { // get byte position
+ return this.byteOffset;
+ },
+ setPos: function(byteOffset, bitOffset) { // set byte position
+ this.byteOffset = byteOffset;
+ this.bitOffset = bitOffset;
+ },
+ seek: function(byteDelta, bitDelta) { // relative seek
+ this.byteOffset += byteDelta;
+ this.bitOffset += bitDelta;
+ if (this.bitOffset < 0) {
+ do {
+ this.byteOffset --;
+ this.bitOffset += 8;
+ } while (this.bitOffset < 0);
+ } else if (this.bitOffset > 7) {
+ do {
+ this.byteOffset ++;
+ this.bitOffset -= 8;
+ } while (this.bitOffset > 7);
+ }
+ },
+ a: function() { // skip bit
+ if (this.bitOffset) {
+ this.byteOffset++;
+ this.bitOffset = 0;
+ }
+ },
+ b: function() { // bit
+ var value = (this.data[this.byteOffset] >>> (7 - this.bitOffset++)) & 1;
+ if (this.bitOffset === 8) {
+ this.byteOffset++;
+ this.bitOffset = 0;
+ }
+ return value;
+ },
+ ub: function(len) { // unsigned bits
+ var value = 0;
+ while (len--) {
+ value = (value << 1) | this.b();
+ }
+ return value;
+ },
+ sb: function(len) { // signed bits
+ var value = 0;
+ if (len === 0) return 0; // XXX
+ var msb = this.b();
+ if (msb) {
+ var orig_len = len;
+ }
+ while (--len) {
+ value = (value << 1) | this.b();
+ }
+ if (msb) {
+ return value - (1 << (orig_len - 1));
+ }
+ return value;
+ },
+ si8: function() { // snsigned 8-bit integer
+ var value = this.ui8();
+ return (value & 0x80)?(value - 0x100):value;
+ },
+ si16: function() { // snsigned 16-bit integer
+ var value = this.ui16();
+ return (value & 0x8000)?(value - 0x10000):value;
+
+ },
+ si32: function() { // snsigned 32-bit integer
+ var value = this.ui32();
+ return (value & 0x80000000)?(value - 0x100000000):value;
+ },
+ ui8: function() { // unsigned 8-bit integer
+ this.a();
+ return this.data[this.byteOffset++];
+ },
+ ui16: function() { // unsigned 16-bit integer
+ this.a();
+ return this.data[this.byteOffset++] |
+ (this.data[this.byteOffset++] << 8);
+ },
+ ui32: function() { // unsigned 32-bit integer
+ this.a();
+ return this.data[this.byteOffset++] |
+ (this.data[this.byteOffset++] << 8) |
+ (this.data[this.byteOffset++] << 16) |
+ (this.data[this.byteOffset++] << 24);
+ },
+ sub: function(len) {
+ this.a();
+ var data = this.data.subarray(this.byteOffset, this.byteOffset + len);
+ this.byteOffset += len;
+ return data;
+ },
+ strN: function(len) {
+ this.a();
+ var data = this.data;
+ var str = [];
+ for (var i = this.byteOffset, l = this.byteOffset + len ; i < len ; i++) {
+ str.push(String.fromCharCode(data[i]))
+ }
+ this.byteOffset += len;
+// return new FlappUTF8().fromSJISArray(data);
+ return str.join('');
+ },
+ str: function(len) {
+ this.a();
+ var byteOffset = this.byteOffset;
+ var dataLen = this.dataLen;
+ var data;
+ for (var i = byteOffset ; i < dataLen ; i++) {
+ if (this.data[i] === 0) {
+ data = this.strN(i - byteOffset);
+ this.byteOffset++; // skip "\0"
+ return data;
+ }
+ }
+ return this.strN(i - byteOffset);
+ }
+};
+
+});
--- /dev/null
+goog.provide('FlappLoader');
+goog.require('FlappIBit');
+goog.require('FlappSWFHeader')
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappLoader = function(flapp) {
+ this.flapp = flapp;
+};
+
+FlappLoader.prototype = {
+ fromURL: function(url, dict, movieClip) {
+ console.debug("FlappLoader.prototype.fromURL("+url+",flapp,dict,movieClip");
+ var xhr = new XMLHttpRequest();
+ var ibit = new FlappIBit();
+ var loader = this;
+ this.header = null;
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState > 1) {
+ if (xhr.status == 200) {
+ if (xhr.responseText) {
+ ibit.input(xhr.responseText);
+ loader.parse(ibit, dict, movieClip);
+ }
+ }
+ }
+ };
+ xhr.open('GET', url);
+ // xhr.responseType = 'arraybuffer';
+ xhr.overrideMimeType('text/plain; charset=x-user-defined');
+ xhr.send(null);
+ },
+ parse: function(ibit, dict, movieClip) {
+ // console.debug("FlappLoader.prototype.parse");
+ if (ibit.len() < 20) { // 20 is minumum size for swf header, maybe.
+ return ;
+ }
+ if (this.header === null) {
+ this.header = FlappSWFHeader.load(ibit);
+ console.debug(this.header);
+ this.flapp.setHeader(this.header);
+ }
+ var jpegTables = null;
+ while (ibit.a(), ibit.hasNext(2)) {
+ var headPos = ibit.getBytePos();
+ var tag_and_length = ibit.ui16(); // tag and length
+ var code = tag_and_length >>> 6;
+ var length = tag_and_length & 0x3f;
+ if (length === 0x3f) {
+ if (ibit.hasNext(4) === false) {
+ ibit.setPos(headPos, 0);
+ break;
+ }
+ length = ibit.ui32();
+ }
+ if (ibit.hasNext(length) === false) {
+ ibit.setPos(headPos, 0);
+ break;
+ }
+ var startOfContent = ibit.getBytePos();
+ var tag = new FlappSWFTag.load(code, length, ibit);
+// console.debug(tag);
+ switch (code) {
+ case 1: // ShowFrame
+ movieClip.appendControlTag(tag);
+ break;
+ case 2: // DefineShape
+ case 22: // DefineShape2
+ case 32: // DefineShape3
+ dict.set(tag.id, tag);
+ break;
+ case 6: // DefineBits(JPEG)
+ var jpeg = FlappBitmap.toJpeg(tag.jpegData, jpegTables);
+ var image = new Image();
+ image.src = "data:image/jpeg;base64," + goog.global.btoa(jpeg);
+ tag.image = image;
+ dict.set(tag.id, tag);
+ break;
+ case 8: // JPEGTables
+ jpegTables = tag;
+ break;
+ case 9: // SetBackgroundColor
+ // set canvas background
+ break;
+ case 12: // DoAction
+ movieClip.appendControlTag(tag);
+ break;
+ case 26: // PlaceObject2
+ movieClip.appendControlTag(tag);
+ break;
+ default:
+ console.warn("Unknown swf tag code:"+code);
+ break;
+ }
+ ibit.setPos(startOfContent + length, 0);
+ }
+ }
+};
+
+});
--- /dev/null
+goog.provide('Flapp');
+goog.require('FlappLoader');
+goog.require('FlappDict');
+goog.require('FlappCanvas');
+goog.require('FlappMovieClip');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+Flapp = function(url, canvas_id) {
+ console.debug("Flapp("+url+","+canvas_id+")");
+ this.url = url;
+ this.canvas_id = canvas_id;
+ this.canvas = document.getElementById(canvas_id);
+ goog.global.flapp = this; // debug
+ this.header = null
+// this.frameTick = 1000 / 10; // default 0.1[sec]
+ this.frameTick = 1000; // default
+};
+Flapp.prototype = {
+ play: function() {
+ console.debug("Flapp.prototype.play");
+ var flapp = this;
+ var loader = new FlappLoader(flapp); // file loader
+ this.dict = new FlappDict(); // content dictionary
+ this.movieClip = new FlappMovieClip(); // root MC
+ loader.fromURL(this.url, this.dict, this.movieClip);
+ this.canvas = new FlappCanvas(this.canvas);
+ this.run(this.dict, this.movieClip, this.canvas);
+ },
+ setHeader: function(header) {
+// this.frameTick = 1000 / header.framerate;
+ this.frameTick = 1000;
+ this.movieClip.totalframes = header.framecount;
+ },
+ run: function(dict, movieClip, canvas) {
+ console.debug("Flapp::run");
+ var flapp = this;
+ this.canvas = canvas;
+ this.tick(flapp, this.dict, this.movieClip);
+ },
+ tick: function(flapp, dict, movieClip) {
+ console.debug("Flapp::tick "+movieClip.currentFrame);
+ setTimeout(flapp.tick, flapp.frameTick, flapp, dict, movieClip);
+ if (movieClip.control(dict)) {
+ movieClip.action();
+ movieClip.render(flapp.canvas);
+ movieClip.increment();
+ }
+ }
+};
+
+goog.exportSymbol('Flapp', Flapp);
+goog.exportSymbol('Flapp.prototype.play', Flapp.prototype.play);
+
+});
--- /dev/null
+goog.provide('FlappMemory');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappMemory = function() {
+ ;
+};
+
+FlappMemory.prototype = {
+ add: function(key, content) {
+ ;
+ },
+ del: function(key, content) {
+ ;
+ }
+};
+
+});
--- /dev/null
+goog.provide('FlappMovieClip');
+goog.require('FlappDisplay');
+goog.require('FlappShape');
+goog.require('FlappAction');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappMovieClip = function(parentMovieClip, name, matrix, colorTransform) {
+ this.OBJECT_TYPE = 2; // 1:Shape, 2: MovieClip
+ this.parentMovieClip = parentMovieClip?parentMovieClip:null;
+ this.rootMovieClip = parentMovieClip?parentMovieClip.rootMovieClip:this;
+ this.name = name?name:'anonymous';
+ this.matrix = matrix;
+ this.colorTransform = colorTransform;
+ this.childMovieClips = {}; // name => movieClip
+ this.childMovieClips_seqnum = 1; // for name movieClip
+ this.clearControlTags();
+ //
+ this.prevShowFramePos = 0;
+ //
+ var canvas = document.createElement('canvas');
+ canvas.width = 240; // XXX
+ canvas.height = 240; // XXX
+ this.canvas = canvas;
+ this.canvasDirty = false; // dirtyFlag
+ //
+ this.displayList = new FlappDisplay();
+ //
+ this.totalframes = 0;
+ this.currentFrame = 0;
+ this.playing = true;
+ // this.loop = true;
+ this.loop = false;
+ this.actionVarriableTable = {};
+ this.actionVarriablOrigKeys = {};
+};
+
+FlappMovieClip.prototype = {
+ clearControlTags: function(controlTag) {
+ this.controlTagsList = [[]]; //
+ this.actionTagsList = [[]];
+ this.labelMap = {}; // label => frameNum
+ this.framesLoaded = 0;
+ },
+ appendControlTag: function(controlTag) {
+ // console.debug("FlappMovieClip::appendControlTag");
+ if (controlTag.code === 12) { // DoAction
+ this.actionTagsList[this.framesLoaded].push(controlTag);
+ return ;
+ }
+ this.controlTagsList[this.framesLoaded].push(controlTag);
+ if (controlTag.code === 1) { // ShowFrame
+ this.controlTagsList.push([]);
+ this.actionTagsList.push([]);
+ this.framesLoaded++;
+ } else if (controlTag.code === 43) { // FrameLabel
+ this.labelMap[controlTag.name] = this.framesLoaded;
+ }
+ },
+ setControlTags: function(controlTags) {
+ this.clearControlTags();
+ for (var i = 0, l = controlTags.length ; i < l ; i++) {
+ this.appendControlTag(controlTags[i]);
+ }
+ },
+ addChildMovieClip: function(name, movieClip) {
+ this.childMovieClips[name] = movieClip;
+ },
+ deleteChildMovieClip: function(name) {
+ delete this.childMovieClips[name];
+ },
+ control: function(dict) {
+ if (this.totalframes === 0) { // imcomplete
+ return false;
+ }
+ console.debug("FlappMovieClip::control");
+ if (this.framesLoaderd < this.totalframes) { // imcomplete
+ if (this.currentFrame < this.framesLoaderd) {
+ return false; // idle
+ }
+ }
+ for (var mc in this.childMovieClips) {
+ this.childMovieClips[mc].control(dict);
+ }
+ if (this.playing) {
+ this.controlThis(dict);
+ }
+ return true;
+ },
+ controlThis: function(dict) {
+ console.debug("FlappMovieClip::controlThis");
+ var tag, i, l;
+ var defineTag;
+ if ((this.currentFrame < 0 ) || (this.totalframes <= this.currentFrame)) {
+ this.currentFrame = 0;
+ }
+ var controlTags = this.controlTagsList[this.currentFrame];
+
+ for (i = 0, l = controlTags.length ; i < l ; i++) {
+ tag = controlTags[i];
+ switch (tag.code) {
+ case 1: // ShowFrame
+ break;
+ case 26: // PlaceObject2
+ // set display List;
+ var obj = null;
+ if (tag.move) {
+ this.displayList.set(tag.depth, obj, tag);
+ } else {
+ defineTag = dict.get(tag.id);
+ console.log(tag);
+ if (defineTag.code === 39) { // DefineSprite
+ var name = tag.name;
+ if (name === null) {
+ name = "instance"+this.childMovieClips_seqnum;
+ defineTag.name = name;
+ this.childMovieClips_seqnum++;
+ }
+ var obj = FlappMovieClip(this, name, tag.matrix, tag.colorTransform);
+ obj.setControlTags(defineTag.controlTags);
+ this.addChildMovieClip(name, obj);
+ } else if (defineTag.code === 2) { // DefineShape
+ var obj = new FlappShape(name, tag.matrix, tag.colorTransform);
+ console.log(obj);
+ obj.loadShapeTag(defineTag);
+ }
+ this.displayList.set(tag.depth, obj, tag);
+ break;
+ }
+ }
+ }
+ },
+ action: function() {
+ for (var mc in this.childMovieClips) {
+ this.childMovieClips[mc].action();
+ }
+ if (this.playing) {
+ this.actionThis();
+ }
+
+ },
+ actionThis: function() {
+ var actionTags = this.actionTagsList[this.currentFrame];
+ var l = actionTags.length;
+ console.debug("FlappMovieClip::actionThis: actionTags.length:"+l);
+ for (var i = 0 ; i < l ; i++) {
+ var tag = actionTags[i];
+ var movieClip = this;
+ FlappAction.exec(tag, movieClip, this.rootMovieClip);
+ }
+ },
+ increment: function() {
+ for (var mc in this.childMovieClips) {
+ this.childMovieClips[mc].increment();
+ }
+ if (this.playing) {
+ this.incrementThis();
+ }
+ },
+ incrementThis: function() {
+ console.debug("FlappMovieClip::incrementThis: "+this.currentFrame);
+ this.currentFrame++;
+ if (this.totalframes <= this.currentFrame) {
+ if (this.loop) {
+ this.currentFrame = 0; // play
+ } else {
+ this.playing = false;
+ }
+ }
+ if (this.totalframes === 1) {
+ this.playing = false;
+ }
+ },
+ render: function(canvas) {
+ var depthList = this.displayList.descSortedDepth();
+ for (var i = 0, l = depthList.length ; i < l ; i++) {
+ var depth = depthList[i];
+ var obj = this.displayList.getObj(depth);
+ if (obj.OBJECT_TYPE === 2) { // MovieClip
+ obj.render(this.canvas);
+ } else if ((obj.OBJECT_TYPE === 2) && (this.playing == true)) {
+ obj.render(this.canvas);
+ }
+ }
+ },
+ setVariable: function(key, value) {
+ var lcKey = key.toLowerCase();
+ this.actionVarriableTable[lcKey] = value;
+ this.actionVarriablOrigKeys[lcKey] = key;
+ },
+ getVariable: function(key) {
+ var lcKey = key.toLowerCase();
+ if (lcKey in this.actionVarriableTable) {
+ return this.actionVarriableTable[lcKey];
+ }
+ return null;
+ },
+ gotoFrame: function(frameNum) {
+ console.debug("FlappMovieClip::gotoFrame"+frameNum);
+ this.currentFrame = frameNum;
+ },
+ gotoLabel: function(frameLabel) {
+ var frameNum = this.labelMap[frameLabel];
+ console.debug("FlappMovieClip::gotoFrame"+frameLabel+"=>"+frameNum);
+ this.currentFrame = frameNum;
+ },
+ play: function() {
+ this.playing = true;
+ },
+ stop: function() {
+ this.playing = false;
+ },
+ destroy: function() { // destructor
+ for (var name in this.childMovieClips) {
+ this.childMovieClips[name].destroy();
+ }
+ this.parentMovieClip = null;
+ this.rootMovieClip = null;
+ this.controlTagsList = null;
+ this.actionTagsList = null;
+ this.labelMap = null;
+ this.canvas = null;
+ this.displayList = null;
+ }
+};
+
+});
--- /dev/null
+goog.provide('FlappShape');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappShape = function(name, matrix, colorTransform) {
+ this.OBJECT_TYPE = 1; // 1:Shape, 2:MovieClip
+ this.canvas = document.createElement('canvas');
+ this.canvas.width = 240; // XXX
+ this.canvas.height = 240; // XXX
+ this.renderCode = "";
+};
+
+FlappShape.prototype = {
+ loadShapeTag: function(shape) {
+ ;
+ },
+ render: function(canvas) {
+ ;
+ }
+};
+
+
+FlappShape.shapetoRenderCode = function(shapeTag) {
+ ;
+};
+
+});
--- /dev/null
+goog.provide('FlappString');
+
+var SJISToUTF8 = {};
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappString = function() {
+ ;
+};
+
+FlappString.ArrayToString = function(sjisArray) {
+ var strArray = [];
+ for (var i = 0, l = sjisArray.length ; i < l ; i++) {
+ strArray.push(String.fromCharCode(sjisArray[i]));
+ }
+ return strArray.join('');
+};
+
+FlappString.SJISArrayToString = function(sjisArray) {
+ console.log("FlappString::SJISArrayToString");
+ var string = FlappString.ArrayToString(sjisArray);
+ if (string in SJISToUTF8) {
+ return SJISToUTF8[string];
+ }
+ SJISToUTF8[string] = string; // dummy string
+ var b = new Blob([sjisArray]);
+ var fr = new FileReader();
+ fr.onloadend = function() {
+ SJISToUTF8[string] = this.result;
+ };
+ fr.readAsText(b, "sjis");
+
+ return string;
+};
+
+FlappString.SJISToUTF8 = function(string) {
+ if (string in SJISToUTF8) {
+ return SJISToUTF8[string];
+ }
+ return null;
+};
+
+FlappString.SJISArrayMBLength = function(sjis){
+ var len = 0;
+ for (var i = 0, l = sjis.length ; i < l ; i++) {
+ if (sjis[i] & 0x80) {
+ i++;
+ }
+ len ++;
+ }
+ return len;
+};
+
+FlappString.SJISArrayMBExtract = function(sjis){
+ var extractedSJIS = [];
+ for (var i = 0, l = sjis.length ; i < l ; i++) {
+ if (sjis[i] & 0x80) {
+ extractedSJIS.join([sjis[i++], sjis[i]]);
+ } else {
+ extractedSJIS.join([sjis[i]]);
+ }
+ }
+ return extractedSJIS;
+}
+
+});
--- /dev/null
+goog.provide('FlappSWFCXForm');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFCXForm = function(ibit) {
+ ;
+};
+
+FlappSWFCXForm.load = function(ibit, hasAlpha) {
+ ibit.a();
+ var hasAddTerms = ibit.b();
+ var hasMultiTerms = ibit.b();
+ var nBits = ibit.ub(4);
+ if (hasMultiTerms) {
+ var redMultiTerm = ibit.sb(nBits);
+ var greenMultiTerm = ibit.sb(nBits);
+ var blueMultiTerm = ibit.sb(nBits);
+ if (hasAlpha) {
+ var alphaMultiTerm = ibit.sb(nBits);
+ }
+ } else {
+ var redMultiTerm = 256;
+ var greenMultiTerm = 256;
+ var blueMultiTerm = 256;
+ if (hasAlpha) {
+ var alphaMultiTerm = 256;
+ }
+ }
+ if (hasAddTerms) {
+ var redAddTerm = ibit.sb(nBits);
+ var greenAddTerm = ibit.sb(nBits);
+ var blueAddTerm = ibit.sb(nBits);
+ if (hasAlpha) {
+ var alphaAddTerm = ibit.sb(nBits);
+ }
+ } else {
+ var redAddTerm = 0;
+ var greenAddTerm = 0;
+ var blueAddTerm = 0;
+ if (hasAlpha) {
+ var alphaAddTerm = 0;
+ }
+ }
+ return {
+ redMultiTerm:redMultiTerm,
+ greenMultiTerm:greenMultiTerm,
+ blueMultiTerm:blueMultiTerm,
+ redAddTerm:redAddTerm,
+ greenAddTerm:greenAddTerm,
+ blueAddTerm:blueAddTerm
+ };
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFFillStyles');
+goog.require('FlappSWFMatrix');
+goog.require('FlappSWFGradient');
+goog.require('FlappSWFRGBA');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFFillStyles = function(ibit) {
+ ;
+};
+
+FlappSWFFillStyles.load = function(code, ibit) {
+ ibit.a();
+ var count = ibit.ui8();
+ if ((code > 2) && (count === 0xff)) {
+ count = ibit.ui16();
+ }
+ var fillStyles = new Array(count);
+ var hasAlpha = (code < 32)?false:true;
+ for (var i = 0 ; i < count ; i++) {
+ fillStyles[i] = FlappSWFFillStyles.loadStyle(ibit, hasAlpha);
+ }
+ return fillStyles;
+};
+
+FlappSWFFillStyles.loadStyle = function(ibit, hasAlpha) {
+ ibit.a();
+ var type = ibit.ui8();
+ var style = {type: type};
+ switch (type) {
+ case 0x00: // solid fill
+ style.color = FlappSWFRGBA.load(ibit, hasAlpha);
+ break;
+ case 0x10: // linear gradient fill
+ case 0x12: // radial gradient fill
+ style.matrix = FlappSWFMatrix.load(ibit);
+ style.gradient = new FlappSWFGradient(ibit, hasAlpha);
+ break;
+ case 0x13: // focal radial gradient fill
+ style.matrix = FlappSWFMatrix.load(ibit);
+ style.gradient = new FlappSWFGradient(ibit, hasAlpha);
+ break;
+ case 0x40: // repeating bitmap fill
+ case 0x41: // clipped bitmap fill
+ case 0x42: // non-smoothed repeating bitmap
+ case 0x43: // non-smoothed clipped bitmap
+ style.bitmapId = ibit.ui16();
+ style.matrix = FlappSWFMatrix.load(ibit);
+ break;
+ }
+ return style;
+}
+
+});
--- /dev/null
+goog.provide('FlappSWFGradient');
+goog.require('FlappSWFRGBA');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFGradient = function(ibit) {
+ ;
+};
+
+FlappSWFGradient.load = function(code, ibit) {
+ var hasAlpha = !(code<32);
+ ibit.a();
+ var bs; // TODO
+ var spread = bs.getUIBits(2);
+ var interpolationMode = bs.getUIBits(2);
+ var numGradients = bs.getUIBits(4);
+ this.NumGradients = numGradients;
+ var gradientRecords = [];
+ for (var i = 0 ; i < numGradients ; i++) {
+ var ratio = ibit.ui8();
+ var color = FlappSWFRGBA.load(ibit, hasAlpha);
+ gradientRecords.push({ratio:ratio, color:color});
+ }
+ return {
+ spreadMode: spread,
+ interpolationMode: interpolationMode,
+ gradientRecords: gradientRecords
+ };
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFHeader');
+goog.require('FlappSWFRect');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFHeader = function() {
+ ;
+};
+
+FlappSWFHeader.load = function(ibit) {
+ return { signature: ibit.strN(3),
+ version: ibit.ui8(),
+ filesize: ibit.ui32(),
+ framesize: FlappSWFRect.load(ibit),
+ framerate: ibit.ui16() / 0x100,
+ framecount: ibit.ui16()
+ };
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFLineStyles');
+goog.require('FlappSWFRGBA');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFLineStyles = function(ibit) {
+ ;
+};
+
+FlappSWFLineStyles.load = function(code, ibit) {
+ ibit.a();
+ var count = ibit.ui8();
+ if ((code > 2) && (count === 0xff)) {
+ count = ibit.ui16();
+ }
+ var lineStyles = new Array(count);
+ var hasAlpha = !(code < 32);
+ for (var i = 0 ; i < count ; i++) {
+ lineStyles[i] = FlappSWFLineStyles.loadStyle(ibit, hasAlpha);
+ }
+ return lineStyles;
+};
+
+FlappSWFLineStyles.loadStyle = function(ibit, hasAlpha) {
+ var width = ibit.ui16();
+ var color = FlappSWFRGBA.load(ibit, hasAlpha);
+ return {width:width, color:color};
+}
+
+});
--- /dev/null
+goog.provide('FlappSWFMatrix');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFMatrix = function(ibit) {
+ ;
+};
+
+FlappSWFMatrix.identity = function() {
+ return { scaleX:1, scaleY:1, skew0:0, skew1:0, transX:0, transY:0 };
+};
+
+FlappSWFMatrix.load = function(ibit) {
+ ibit.a();
+ if (ibit.b()) { // HasScale
+ var nScaleBits = ibit.ub(5);
+ var scaleX = ibit.sb(nScaleBits) / 0x10000;
+ var scaleY = ibit.sb(nScaleBits) / 0x10000;
+ } else {
+ var scaleX = 1;
+ var scaleY = 1;
+ }
+ if (ibit.b()) { // HasSkew
+ var nSkewBits = ibit.ub(5);
+ var skew0 = ibit.sb(nSkewBits) / 0x10000;
+ var skew1 = ibit.sb(nSkewBits) / 0x10000;
+ } else {
+ var skew0 = 0;
+ var skew1 = 0;
+ }
+ var nTransBits = ibit.ub(5);
+ var transX = ibit.sb(nTransBits);
+ var transY = ibit.sb(nTransBits);
+
+ return { scaleX:scaleX, scaleY:scaleY, skew0:skew0, skew1:skew1,
+ transX:transX, transY:transY
+ };
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFRect');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFRect = function(ibit) {
+ ;
+};
+
+FlappSWFRect.load = function(ibit) {
+ ibit.a();
+ var nbit = ibit.ub(5);
+ return {
+ xmin: ibit.sb(nbit),
+ xmax: ibit.sb(nbit),
+ ymin: ibit.sb(nbit),
+ ymax: ibit.sb(nbit)
+ };
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFRGBA');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFRGBA = function(ibit) {
+ ;
+};
+
+FlappSWFRGBA.load = function(ibit, hasAlpha) {
+ ibit.a();
+ if (hasAlpha) {
+ return {
+ red: ibit.ui8(),
+ green: ibit.ui8(),
+ blue: ibit.ui8(),
+ alpha: ibit.ui8()
+ };
+ }
+ return {
+ red: ibit.ui8(),
+ green: ibit.ui8(),
+ blue: ibit.ui8(),
+ alpha: 255
+ };
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFShapeRecords');
+goog.require('FlappSWFFillStyles');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFShapeRecords = function(ibit) {
+ ;
+};
+
+FlappSWFShapeRecords.load = function(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits) {
+ var shapeRecords = []; // [[fillstyle0, fillstyle1, linestyle, edgetypes, [edges]], [], ...]
+ var fillStyleBaseIndex = 0;
+ var lineStyleBaseIndex = 0;
+ var fillStyle0 = 0, fillStyle1 = 0, lineStyle = 0;
+ var currentX = 0, currentY = 0;
+ ibit.a();
+ var edgetypearray = ['M'];
+ var edges = [currentX, currentY];
+ var first6bits;
+ while (first6bits = ibit.ub(6)) {
+ if (first6bits & 0x20) { // Edge (1XXXXX)
+ var numBits = first6bits & 0x0F;
+ if (first6bits & 0x10) { // Straight Edge (11XXXX)
+ var deltaX = 0, deltaY = 0;
+ var generalLine = ibit.b();
+ if (generalLine) { // Straight Edge
+ deltaX = ibit.sb(numBits + 2);
+ deltaY = ibit.sb(numBits + 2);
+ } else { // Straight Edge
+ var vertLine = ibit.b();
+ if (vertLine) { // Straight Edge
+ deltaY = ibit.sb(numBits + 2);
+ } else {
+ deltaX = ibit.sb(numBits + 2);
+ }
+ }
+ var x = currentX + deltaX;
+ var y = currentY + deltaY;
+ edgetypearray.push('S');
+ edges.push(x, y);
+ currentX = x;
+ currentY = y;
+ } else { // Curved Edge (10XXXX)
+ var controlDeltaX = ibit.sb(numBits + 2);
+ var controlDeltaY = ibit.sb(numBits + 2);
+ var anchorDeltaX = ibit.sb(numBits + 2);
+ var anchorDeltaY = ibit.sb(numBits + 2);
+ var controlX = currentX + controlDeltaX;
+ var controlY = currentY + controlDeltaY;
+ var anchorX = controlX + anchorDeltaX;
+ var anchorY = controlY + anchorDeltaY;
+ edgetypearray.push('C');
+ edges.push(controlX, controlY,
+ anchorX, anchorY);
+ currentX = anchorX;
+ currentY = anchorY;
+ }
+ } else if (first6bits) { // Change (0XXXXX != 000000)
+ if (edgetypearray.length > 1) {
+ shapeRecords.push(
+ [fillStyle0, fillStyle1, lineStyle, edgetypearray.join(''),
+ edges]
+ );
+ }
+ if (first6bits & 0x10) { // StateNewStyles
+ fillStyleBaseIndex = fillStyles.length;
+ lineStyleBaseIndex = lineStyles.length;
+ var appendFillStyles = FlappSWFFillStyles.load(code, ibit);
+ var appendLineStyles = FlappSWFLineStyles.load(code, ibit);
+ var extendFillStyles = [];
+ var extendLineStyles = [];
+ for (var i = 0, l = fillStyles.length ; i < l ; i++) {
+ extendFillStyles.push(fillStyles[i]);
+ }
+ for (var i = 0, l = appendFillStyles.length ; i < l ; i++) {
+ extendFillStyles.push(appendFillStyles[i]);
+ }
+ for (var i = 0, l = lineStyles.length ; i < l ; i++) {
+ extendLineStyles.push(lineStyles[i]);
+ }
+ for (var i = 0, l = appendLineStyles.length ; i < l ; i++) {
+ extendLineStyles.push(appendLineStyles[i]);
+ }
+ fillStyles = extendFillStyles;
+ lineStyles = extendFillStyles;
+ ibit.a();
+ var numBits = ibit.ui8();
+ numFillBits = numBits >> 4;
+ numLineBits = numBits & 0x0f;
+ fillStyleBaseIndex = fillStyles.length;
+ lineStyleBaseIndex = lineStyles.length;
+ }
+ if (first6bits & 1) { // StateMoveTo
+ var moveBits = ibit.ub(5);
+ currentX = ibit.sb(moveBits); // MoveDeltaX(?)
+ currentY = ibit.sb(moveBits); // MoveDeltaY(?)
+ }
+ if (first6bits & 2) { // StateFillStyle0
+ fillStyle0 = ibit.ub(numFillBits);
+ if (fillStyle0) {
+ fillStyle0 += fillStyleBaseIndex;
+ }
+ }
+ if (first6bits & 4) { // StateFillStyle1
+ fillStyle1 = ibit.ub(numFillBits);
+ if (fillStyle1) {
+ fillStyle1 += fillStyleBaseIndex;
+ }
+ }
+ if (first6bits & 8) { // StateLineStyle
+ lineStyle = ibit.ub(numLineBits);
+ if (lineStyle) {
+ lineStyle += lineStyleBaseIndex;
+ }
+ }
+ edgetypearray = ['M'];
+ edges = [currentX, currentY];
+ }
+ }
+ if (edgetypearray.length > 1) {
+ shapeRecords.push(
+ [fillStyle0, fillStyle1, lineStyle, edgetypearray.join(''),
+ edges]
+ );
+ }
+ return shapeRecords;
+};
+
+});
--- /dev/null
+goog.provide('FlappSWFTag');
+goog.require('FlappSWFTagShowFrame');
+goog.require('FlappSWFTagDefineShape');
+goog.require('FlappSWFTagDefineBitsJPEG');
+goog.require('FlappSWFTagJPEGTables');
+goog.require('FlappSWFTagSetBackgroundColor');
+goog.require('FlappSWFTagDoAction');
+goog.require('FlappSWFTagPlaceObject');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTag = function() {
+ ;
+};
+
+// tag factory
+FlappSWFTag.load = function(code, length, ibit) {
+// console.log("FlappSWFTag.load(code:"+code+", length:"+length+", ibit)");
+ var tag = null;
+ switch (code) {
+ case 1: // ShowFrame
+ tag = new FlappSWFTagShowFrame(code, length, ibit);
+ break;
+ case 2: // DefineShape
+ case 22: // DefineShape2
+ case 32: // DefineShape3
+ tag = new FlappSWFTagDefineShape(code, length, ibit);
+ break;
+ case 6: // DefineBits(JPEG)
+ tag = new FlappSWFTagDefineBitsJPEG(code, length, ibit);
+ break;
+ case 8: // JPEGTables
+ tag = new FlappSWFTagJPEGTables(code, length, ibit);
+ break;
+ case 9: // SetBackgroundColor
+ tag = new FlappSWFTagSetBackgroundColor(code, length, ibit);
+ break;
+ case 12: // DoAction
+ tag = new FlappSWFTagDoAction(code, length, ibit);
+ break;
+ case 26: // PlaceObject2
+ tag = new FlappSWFTagPlaceObject(code, length, ibit);
+ break;
+ }
+// console.debug(tag);
+ return tag;
+};
+
+});
--- /dev/null
+/*
+ DefineBitsJPEG parser
+*/
+goog.provide('FlappSWFTagDefineBitsJPEG');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagDefineBitsJPEG = function(code, length, ibit) {
+// console.log("FlappSWFTagDefineBitsJPEG(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+ this.id = ibit.ui16();
+ if (code <= 21) { // DefineBits & DefineBitsJPEG2
+ this.jpegData = ibit.sub(length - 2);
+ } else {
+ var alphaDataOffset = ibit.ui32();
+ this.jpegData = ibit.sub(alphaDataOffset);
+ this.abitmapAlphaData = (length - 2 - alphaDataOffset);
+ }
+};
+
+});
--- /dev/null
+/*
+ DefineShape parser
+*/
+goog.provide('FlappSWFTagDefineShape');
+goog.require('FlappSWFShapeRecords');
+goog.require('FlappSWFFillStyles');
+goog.require('FlappSWFLineStyles');
+goog.require('FlappSWFRect');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagDefineShape = function(code, length, ibit) {
+// console.log("FlappSWFTagDefineShape(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+ this.id = ibit.ui16();
+ this.bounds = FlappSWFRect.load(ibit);
+ var fillStyles = FlappSWFFillStyles.load(code, ibit);
+ var lineStyles = FlappSWFLineStyles.load(code, ibit);
+ ibit.a();
+ var numBits = ibit.ui8();
+ var numFillBits = numBits >> 4;
+ var numLineBits = numBits & 0x0f;
+ this.fillStyles = fillStyles;
+ this.lineStyles = lineStyles;
+ this.shapes = FlappSWFShapeRecords.load(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits);
+};
+
+});
--- /dev/null
+/*
+ DoAction parser
+*/
+goog.provide('FlappSWFTagDoAction');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagDoAction = function(code, length, ibit) {
+// console.log("FlappSWFTagDoAction(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+ //
+ this.actions = ibit.sub(length);
+};
+
+});
--- /dev/null
+/*
+ JPEGTables parser
+*/
+goog.provide('FlappSWFTagJPEGTables');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagJPEGTables = function(code, length, ibit) {
+// console.log("FlappSWFTagJPEGTables(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+ //
+ this.jpegData = ibit.sub(length);
+};
+
+});
--- /dev/null
+/*
+ PlaceObject parser
+*/
+goog.provide('FlappSWFTagPlaceObject');
+goog.require('FlappSWFMatrix');
+goog.require('FlappSWFCXForm');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagPlaceObject = function(code, length, ibit) {
+// console.log("FlappSWFTagPlaceObject(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+ //
+ if (code === 26) { // PlaceObject2
+ var placeFlag = ibit.ui8();
+ var placeFlagHasClipActions = (placeFlag & 0x80);
+ var placeFlagHasClipDepth = (placeFlag & 0x40);
+ var placeFlagHasName = (placeFlag & 0x20);
+ var placeFlagHasRatio = (placeFlag & 0x10);
+ var placeFlagHasColorTransform = (placeFlag & 0x08);
+ var placeFlagHasMatrix = (placeFlag & 0x04);
+ var placeFlagHasCharacter = (placeFlag & 0x02);
+ var placeFlagMove = (placeFlag & 0x01);
+ this.move = placeFlagMove;
+ this.depth = ibit.ui16();
+ this.id = (placeFlagHasCharacter)?ibit.ui16():null;
+ this.matrix = (placeFlagHasMatrix)?FlappSWFMatrix.load(ibit):null;
+ this.colorTransform = (placeFlagHasColorTransform)?FlappSWFCXForm(ibit, true):null;
+ this.ratio = (placeFlagHasRatio)?ibit.ui16():null;
+ this.name = (placeFlagHasName)?ibit.str():null;
+ this.clipDepth = (placeFlagHasClipDepth)?ibit.ui16():null;
+ // ClipActions swf5 later
+ } else if (code === 4) { // PlaceObject
+ this.id = ibit.ui16();
+ this.depth = ibit.ui16();
+ this.matrix = FlappSWFMatrix.load(ibit);
+ ibit.a();
+ this.colorTransform = (ibit.hasNext(1))?FlappSWFCXForm(ibit, false):null;
+ }
+};
+
+});
--- /dev/null
+/*
+ SetBackgroundColor parser
+*/
+goog.provide('FlappSWFTagSetBackgroundColor');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagSetBackgroundColor = function(code, length, ibit) {
+// console.log("FlappSWFTagSetBackgroundColor(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+ //
+ this.red = ibit.ui8();
+ this.green = ibit.ui8();
+ this.blue = ibit.ui8();
+};
+
+});
--- /dev/null
+/*
+ ShowFrame parser
+*/
+goog.provide('FlappSWFTagShowFrame');
+
+goog.scope(function() {
+
+/**
+ * @constructor
+ */
+FlappSWFTagShowFrame = function(code, length, ibit) {
+// console.log("FlappSWFTagShowFrame(code:"+code+", length:"+length+", ibit)");
+ this.code = code;
+ this.length = length;
+};
+
+});
+++ /dev/null
-(function(global) {
- var SJISToUTF8 = {};
- var FlappString = function() {
- ;
- };
-
- FlappString.prototype = {
-
- };
- FlappString.ArrayToString = function(sjisArray) {
- var strArray = [];
- for (var i = 0, l = sjisArray.length ; i < l ; i++) {
- strArray.push(String.fromCharCode(sjisArray[i]));
- }
- return strArray.join('');
- }
- FlappString.SJISArrayToString = function(sjisArray) {
- console.log("FlappString::SJISArrayToString");
- string = FlappString.ArrayToString(sjisArray);
- if (string in SJISToUTF8) {
- return string;
- }
- SJISToUTF8[string] = string; // dummy string
- var b = new Blob([sjisArray]);
- var fr = new FileReader();
- fr.onloadend = function() {
- SJISToUTF8[string] = this.result;
- }
- ret = fr.readAsText(b, "sjis");
- };
- FlappString.SJISToUTF8 = function(string) {
- if (string in SJISToUTF8) {
- return SJISToUTF8[string];
- }
- return null;
- };
- FlappString.SJISArrayMBLength = function(sjis){
- var len = 0;
- for (i = 0, l = sjis.length ; i < l ; i++) {
- if (sjis[i] & 0x80) {
- i++;
- }
- len ++;
- }
- return len;
- };
- FlappString.SJISArrayMBExtract = function(sjis){
- var extractedSJIS = [];
- for (i = 0, l = sjis.length ; i < l ; i++) {
- if (sjis[i] & 0x80) {
- extractedSJIS.join([sjis[i++], sjis[i]]);
- } else {
- extractedSJIS.join([sjis[i]]);
- }
- }
- return extractedSJIS;
- }
- global.FlappString = FlappString;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFCXForm = function(ibit) {
- ;
- };
- FlappSWFCXForm.load = function(ibit, hasAlpha) {
- ibit.a();
- var hasAddTerms = ibit.b();
- var hasMultiTerms = ibit.b();
- var nBits = ibit.ub(4);
- if (hasMultiTerm) {
- var redMultiTerm = ibit.sb(nBits);
- var greenMultiTerm = ibit.sb(nBits);
- var blueMultiTerm = ibit.sb(nBits);
- if (hasAlpha) {
- var alphaMultiTerm = ibit.sb(nBits);
- }
- } else {
- var redMultiTerm = 256;
- var greenMultiTerm = 256;
- var blueMultiTerm = 256;
- if (hasAlpha) {
- var alphaMultiTerm = 256;
- }
- }
- if (hasAddTerms) {
- var redAddTerm = ibit.sb(nBits);
- var greenAddTerm = ibit.sb(nBits);
- var blueAddTerm = ibit.sb(nBits);
- if (hasAlpha) {
- var alphaAddTerm = ibit.sb(nBits);
- }
- } else {
- var redAddTerm = 0;
- var greenAddTerm = 0;
- var blueAddTerm = 0;
- if (hasAlpha) {
- var alphaAddTerm = 0;
- }
- }
- return { redMultiTerm:redMuliTerm,
- greenMultiTerm:greenMultiTerm,
- blueMultiTerm:blueMultiTerm,
- redAddTerm:redAddTerm,
- greenAddTerm:greenAddTerm,
- blueAddTerm:blueAddTerm
- };
- };
-
- global.FlappSWFCXForm = FlappSWFCXForm;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFFillStyles = function(ibit) {
- ;
- };
- FlappSWFFillStyles.load = function(code, ibit) {
- ibit.a();
- var count = ibit.ui8();
- if ((code > 2) && (count === 0xff)) {
- count = ibit.ui16();
- }
- var fillStyles = new Array(count);
- var hasAlpha = (code < 32)?false:true;
- for (var i = 0 ; i < count ; i++) {
- fillStyles[i] = FlappSWFFillStyles.loadStyle(ibit, hasAlpha);
- }
- return fillStyles;
- };
- FlappSWFFillStyles.loadStyle = function(ibit, hasAlpha) {
- ibit.a();
- var type = ibit.ui8();
- var style = {type: type};
- switch (type) {
- case 0x00: // solid fill
- style.color = FlappSWFRGBA.load(ibit, hasAlpha);
- break;
- case 0x10: // linear gradient fill
- case 0x12: // radial gradient fill
- style.matrix = FlappSWFMatrix.load(ibit);
- style.gradient = new FlappSWFGradient(ibit, hasAlpha);
- break;
- case 0x13: // focal radial gradient fill
- style.matrix = FlappSWFMatrix.load(ibit);
- style.gradient = new FlappSWFGradient(ibit, hasAlpha);
- break;
- case 0x40: // repeating bitmap fill
- case 0x41: // clipped bitmap fill
- case 0x42: // non-smoothed repeating bitmap
- case 0x43: // non-smoothed clipped bitmap
- style.bitmapId = ibit.ui16();
- style.matrix = FlappSWFMatrix.load(ibit);
- break;
- }
- return style;
- }
-
- global.FlappSWFFillStyles = FlappSWFFillStyles;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFGradient = function(ibit) {
- ;
- };
- FlappSWFGradient.load = function(code, ibit) {
- var gradientRecords = [];
- var hasAlpha = (code<32)?false:true;
- ibit.a();
- this.SpreadMode = bs.getUIBits(2);
- this.InterpolationMode = bs.getUIBits(2);
- var numGradients = bs.getUIBits(4);
- this.NumGradients = numGradients;
- var gradientRecords = [];
- for (i = 0 ; i < numGradients ; i++) {
- var ratio = ibit.ui8();
- var color = FlappSWFRGBA.load(ibit, hasAlpha);
- gradientRecords.push({ratio:ratio, color:color});
- }
- return { spreadMode: spread,
- interpolationMode: interpolationMode,
- gradientRecords: gradientRecords };
- }
- global.FlappSWFGradient = FlappSWFGradient;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFHeader = function() {
- ;
- };
- FlappSWFHeader.prototype = {
-
- };
- FlappSWFHeader.load = function(ibit) {
- return { signature: ibit.strN(3),
- version: ibit.ui8(),
- filesize: ibit.ui32(),
- framesize: FlappSWFRect.load(ibit),
- framerate: ibit.ui16() / 0x100,
- framecount: ibit.ui16()
- };
- };
-
- global.FlappSWFHeader = FlappSWFHeader;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFLineStyles = function(ibit) {
- ;
- };
- FlappSWFLineStyles.load = function(code, ibit) {
-
- ibit.a();
- var count = ibit.ui8();
- if ((code > 2) && (count === 0xff)) {
- count = ibit.ui16();
- }
- var lineStyles = new Array(count);
- var hasAlpha = (code < 32)?false:true;
- for (var i = 0 ; i < count ; i++) {
- lineStyles[i] = FlappSWFLineStyles.loadStyle(ibit, hasAlpha);
- }
- return lineStyles;
- };
- FlappSWFLineStyles.loadStyle = function(ibit, hasAlpha) {
- var width = ibit.ui16();
- var color = FlappSWFRGBA.load(ibit, hasAlpha);
- return {width:width, color:color};
- }
- global.FlappSWFLineStyles = FlappSWFLineStyles;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFMatrix = function(ibit) {
- ;
- };
- FlappSWFMatrix.identity = function() {
- return { scaleX:1, scaleY:1, skew0:0, skew1:0, transX:0, transY:0 };
- };
- FlappSWFMatrix.load = function(ibit) {
- ibit.a();
- if (ibit.b()) { // HasScale
- var nScaleBits = ibit.ub(5);
- var scaleX = ibit.sb(nScaleBits) / 0x10000;
- var scaleY = ibit.sb(nScaleBits) / 0x10000;
- } else {
- var scaleX = 1;
- var scaleY = 1;
-
- }
- if (ibit.b()) { // HasSkew
- var nSkewBits = ibit.ub(5);
- var skew0 = ibit.sb(nSkewBits) / 0x10000;
- var skew1 = ibit.sb(nSkeweBits) / 0x10000;
- } else {
- var skew0 = 0;
- var skew1 = 0;
- }
- var nTransBits = ibit.ub(5);
- var transX = ibit.sb(nTransBits);
- var transY = ibit.sb(nTransBits);
-
- return { scaleX:scaleX, scaleY:scaleY, skew0:skew0, skew1:skew1,
- transX:transX, transY:transY
- };
- };
-
- global.FlappSWFMatrix = FlappSWFMatrix;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFRect = function(ibit) {
- ;
- };
- FlappSWFRect.load = function(ibit) {
- ibit.a();
- var nbit = ibit.ub(5);
- return { xmin: ibit.sb(nbit),
- xmax: ibit.sb(nbit),
- ymin: ibit.sb(nbit),
- ymax: ibit.sb(nbit) };
- };
-
- global.FlappSWFRect = FlappSWFRect;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFRGBA = function(ibit) {
- ;
- };
- FlappSWFRGBA.load = function(ibit, hasAlpha) {
- ibit.a();
- if (hasAlpha) {
- return { red: ibit.ui8(),
- green: ibit.ui8(),
- blue: ibit.ui8(),
- alpha: ibit.ui8()
- };
- }
- return { red: ibit.ui8(),
- green: ibit.ui8(),
- blue: ibit.ui8(),
- alpha: 255
- };
- }
- global.FlappSWFRGBA = FlappSWFRGBA;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFShapeRecords = function(ibit) {
- ;
- };
- FlappSWFShapeRecords.load = function(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits) {
- var shapeRecords = []; // [[fillstyle0, fillstyle1, linestyle, edgetypes, [edges]], [], ...]
- var fillStyleBaseIndex = 0;
- var lineStyleBaseIndex = 0;
- var fillStyle0 = 0, fillStyle1 = 0, lineStyle = 0;
- var currentX = 0, currentY = 0;
- ibit.a();
- var edgetypearray = ['M'];
- var edges = [currentX, currentY];
- var first6bits;
- while (first6bits = ibit.ub(6)) {
- if (first6bits & 0x20) { // Edge (1XXXXX)
- var numBits = first6bits & 0x0F;
- if (first6bits & 0x10) { // Straight Edge (11XXXX)
- var deltaX = 0, deltaY = 0;
- var generalLine = ibit.b();
- if (generalLine) { // Straight Edge
- deltaX = ibit.sb(numBits + 2);
- deltaY = itib.sb(numBits + 2);
- } else { // Straight Edge
- var vertLine = ibit.b();
- if (vertLine) { // Straight Edge
- deltaY = ibit.sb(numBits + 2);
- } else {
- deltaX = ibit.sb(numBits + 2);
- }
- }
- var x = currentX + deltaX;
- var y = currentY + deltaY;
- edgetypearray.push('S');
- edges.push(x, y);
- currentX = x;
- currentY = y;
- } else { // Curved Edge (10XXXX)
- var controlDeltaX = ibit.sb(numBits + 2);
- var controlDeltaY = ibit.sb(numBits + 2);
- var anchorDeltaX = ibit.sb(numBits + 2);
- var anchorDeltaY = ibit.sb(numBits + 2);
- var controlX = currentX + controlDeltaX;
- var controlY = currentY + controlDeltaY;
- var anchorX = controlX + anchorDeltaX;
- var anchorY = controlY + anchorDeltaY;
- edgetypearray.push('C');
- edges.push(controlX, controlY,
- anchorX, anchorY);
- currentX = anchorX;
- currentY = anchorY;
- }
- } else if (first6bits) { // Change (0XXXXX != 000000)
- if (edgetypearray.length > 1) {
- shapeRecords.push(
- [fillStyle0, fillStyle1, lineStyle, edgetypearray.join(''),
- edges]
- );
- }
- if (first6bits & 0x10) { // StateNewStyles
- fillStyleBaseIndex = fillStyles.length;
- lineStyleBaseIndex = lineStyles.length;
- var appendFillStyles = FlappSWFFillStyles.load(code, ibit);
- var appendLineStyles = FlappSWFLineStyles.load(code, ibit);
- var extendFillStyles = [];
- var extendLineStyles = [];
- for (var i = 0, l = fillStyles.length ; i < l ; i++) {
- extendFillStyles.push(fillStyles[i]);
- }
- for (var i = 0, l = appendFillStyles.length ; i < l ; i++) {
- extendFillStyles.push(appendFillStyles[i]);
- }
- for (var i = 0, l = lineStyles.length ; i < l ; i++) {
- extendLineStyles.push(lineStyles[i]);
- }
- for (var i = 0, l = appendLineStyles.length ; i < l ; i++) {
- extendLineStyles.push(appendLineStyles[i]);
- }
- fillStyles = extendFillStyles;
- lineStyles = extendFillStyles;
- ibit.a();
- var numBits = ibit.ui8();
- numFillBits = numBits >> 4;
- numLineBits = numBits & 0x0f;
- fillStyleBaseIndex = fillStyles.length;
- lineStyleBaseIndex = lineStyles.length;
- }
- if (first6bits & 1) { // StateMoveTo
- var moveBits = ibit.ub(5);
- currentX = ibit.sb(moveBits); // MoveDeltaX(?)
- currentY = ibit.sb(moveBits); // MoveDeltaY(?)
- }
- if (first6bits & 2) { // StateFillStyle0
- fillStyle0 = ibit.ub(numFillBits);
- if (fillStyle0) {
- fillStyle0 += fillStyleBaseIndex;
- }
- }
- if (first6bits & 4) { // StateFillStyle1
- fillStyle1 = ibit.ub(numFillBits);
- if (fillStyle1) {
- fillStyle1 += fillStyleBaseIndex;
- }
- }
- if (first6bits & 8) { // StateLineStyle
- lineStyle = ibit.ub(numLineBits);
- if (lineStyle) {
- lineStyle += lineStyleBaseIndex;
- }
- }
- edgetypearray = ['M'];
- edges = [currentX, currentY];
- }
- }
- if (edgetypearray.length > 1) {
- shapeRecords.push(
- [fillStyle0, fillStyle1, lineStyle, edgetypearray.join(''),
- edges]
- );
- }
- return shapeRecords;
- }
- global.FlappSWFShapeRecords = FlappSWFShapeRecords;
-})(this);
+++ /dev/null
-(function(global) {
- var FlappSWFTag = function() {
- ;
- };
- // tag factory
- FlappSWFTag.load = function(code, length, ibit) {
-// console.log("FlappSWFTag.load(code:"+code+", length:"+length+", ibit)");
- var tag = null;
- switch (code) {
- case 1: // ShowFrame
- tag = new FlappSWFTagShowFrame(code, length, ibit);
- break;
- case 2: // DefineShape
- case 22: // DefineShape2
- case 32: // DefineShape3
- tag = new FlappSWFTagDefineShape(code, length, ibit);
- break;
- case 6: // DefineBits(JPEG)
- tag = new FlappSWFTagDefineBitsJPEG(code, length, ibit);
- break;
- case 8: // JPEGTables
- tag = new FlappSWFTagJPEGTables(code, length, ibit);
- break;
- case 9: // SetBackgroundColor
- tag = new FlappSWFTagSetBackgroundColor(code, length, ibit);
- break;
- case 12: // DoAction
- tag = new FlappSWFTagDoAction(code, length, ibit);
- break;
- case 26: // PlaceObject2
- tag = new FlappSWFTagPlaceObject(code, length, ibit);
- break;
- }
-// console.debug(tag);
- return tag;
- }
- global.FlappSWFTag = FlappSWFTag;
-})(this);
+++ /dev/null
-/*
- DefineBitsJPEG parser
-*/
-
-(function(global) {
- var FlappSWFTagDefineBitsJPEG = function(code, length, ibit) {
-// console.log("FlappSWFTagDefineBitsJPEG(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- this.id = ibit.ui16();
- if (code <= 21) { // DefineBits & DefineBitsJPEG2
- this.jpegData = ibit.sub(length - 2);
- } else {
- var alphaDataOffset = ibit.ui32();
- this.jpegData = ibit.sub(alphaDataOffset);
- this.abitmapAlphaData = (length - 2 - alphaDataOffset);
- }
- }
- global.FlappSWFTagDefineBitsJPEG = FlappSWFTagDefineBitsJPEG;
-})(this);
+++ /dev/null
-/*
- DefineShape parser
-*/
-
-(function(global) {
- var FlappSWFTagDefineShape = function(code, length, ibit) {
-// console.log("FlappSWFTagDefineShape(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- this.id = ibit.ui16();
- this.bounds = FlappSWFRect.load(ibit);
- var fillStyles = FlappSWFFillStyles.load(code, ibit);
- var lineStyles = FlappSWFLineStyles.load(code, ibit);
- ibit.a();
- var numBits = ibit.ui8();
- var numFillBits = numBits >> 4;
- var numLineBits = numBits & 0x0f;
- this.fillStyles = fillStyles;
- this.lineStyles = lineStyles;
- this.shapes = FlappSWFShapeRecords.load(code, ibit, fillStyles, lineStyles, numFillBits, numLineBits);
- }
- global.FlappSWFTagDefineShape = FlappSWFTagDefineShape;
-})(this);
+++ /dev/null
-/*
- DoAction parser
-*/
-
-(function(global) {
- var FlappSWFTagDoAction = function(code, length, ibit) {
-// console.log("FlappSWFTagDoAction(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- //
- this.actions = ibit.sub(length);
- }
- global.FlappSWFTagDoAction = FlappSWFTagDoAction;
-})(this);
+++ /dev/null
-/*
- JPEGTables parser
-*/
-
-(function(global) {
- var FlappSWFTagJPEGTables = function(code, length, ibit) {
-// console.log("FlappSWFTagJPEGTables(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- //
- this.jpegData = ibit.sub(length);
- }
- global.FlappSWFTagJPEGTables = FlappSWFTagJPEGTables;
-})(this);
+++ /dev/null
-/*
- PlaceObject parser
-*/
-
-(function(global) {
- var FlappSWFTagPlaceObject = function(code, length, ibit) {
-// console.log("FlappSWFTagPlaceObject(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- //
- if (code === 26) { // PlaceObject2
- var placeFlag = ibit.ui8();
- var placeFlagHasClipActions = (placeFlag & 0x80)?true:false;
- var placeFlagHasClipDepth = (placeFlag & 0x40)?true:false;
- var placeFlagHasName = (placeFlag & 0x20)?true:false;
- var placeFlagHasRatio = (placeFlag & 0x10)?true:false;
- var placeFlagHasColorTransform = (placeFlag & 0x08)?true:false;
- var placeFlagHasMatrix = (placeFlag & 0x04)?true:false;
- var placeFlagHasCharacter = (placeFlag & 0x02)?true:false;
- var placeFlagMove = (placeFlag & 0x01)?true:false;
- this.move = placeFlagMove;
- this.depth = ibit.ui16();
- this.id = (placeFlagHasCharacter)?ibit.ui16():null;
- this.matrix = (placeFlagHasMatrix)?FlappSWFMatrix.load(ibit):null;
- this.colorTransform = (placeFlagHasColorTransform)?FlappSWFCXForm(ibit, true):null;
- this.ratio = (placeFlagHasRatio)?ibit.ui16():null;
- this.name = (placeFlagHasName)?ibit.str():null;
- this.clipDepth = (placeFlagHasClipDepth)?ibit.ui16():null;
- // ClipActions swf5 later
- } else if (code === 4) { // PlaceObject
- this.id = ibit.ui16();
- this.depth = ibit.ui16();
- this.matrix = FlappSWFMatrix.load(ibit);
- ibit.a();
- this.colorTransform = (ibit.hasNext(1))?FlappSWFCXForm(ibit, false):null;
- }
- }
- global.FlappSWFTagPlaceObject = FlappSWFTagPlaceObject;
-})(this);
+++ /dev/null
-/*
- SetBackgroundColor parser
-*/
-
-(function(global) {
- var FlappSWFTagSetBackgroundColor = function(code, length, ibit) {
-// console.log("FlappSWFTagSetBackgroundColor(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- //
- this.red = ibit.ui8();
- this.green = ibit.ui8();
- this.blue = ibit.ui8();
- }
-
- global.FlappSWFTagSetBackgroundColor = FlappSWFTagSetBackgroundColor;
-})(this);
+++ /dev/null
-/*
- ShowFrame parser
-*/
-
-(function(global) {
- var FlappSWFTagShowFrame = function(code, length, ibit) {
-// console.log("FlappSWFTagShowFrame(code:"+code+", length:"+length+", ibit)");
- this.code = code;
- this.length = length;
- }
- global.FlappSWFTagShowFrame = FlappSWFTagShowFrame;
-})(this);