[
  {
    "path": ".gitignore",
    "content": "_resources/\nbin/\nbin-debug/\nbin-release/\nwiki/\n\n.svn/\n\nThumbs.db\n.DS_Store\nbuild.properties\n\n# Intellij project files\n*.iml\n*.ipr\n*.iws\n.idea/\ntarget/"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2011 the original author or authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "README.textile",
    "content": "h1. Gestouch: multitouch gesture recognition library for Flash (ActionScript) development.\n\nGestouch is a ActionScript (AS3) library that helps you to deal with single- and multitouch gestures for building better NUI (Natural User Interface).\n\n\nh3. Why? There's already gesture support in Flash/AIR!\n\nYes, last versions of Flash Player and AIR runtimes have built-in touch and multitouch support, but the gestures support is very poor: only small set of gestures are supported, they depend on OS, they are not customizable in any way, only one can be processed at the same time and, finally, you are forced to use either raw TouchEvents, or gestures (@see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/Multitouch.html#inputMode).\n_Upd:_ With \"native way\" you also won't get anything out of Stage3D and of custom input like TUIO protocol. \n\n\n\nh3. What Gestouch does in short?\n\nWell basically there's 3 distinctive tasks to solve.\n# To provide various input. It can be native MouseEvents, TouchEvents or more complex things like custom input via TUIO protocol for your hand-made installation. So what we get here is Touches (touch points).\n# To recognize gesture analyzing touches. Each type of Gesture has it's own inner algorithms that ... \n# To manage gestures conflicts. As multiple gestures may be recognized simultaneously, we need to be able to control whether it's allowed or some of them should not be recognized (fail).\n\nGestouch solves these 3 tasks.\nI was hardly inspired by Apple team, how they solved this (quite recently to my big surprise! I thought they had it right from the beginning) in they Cocoa-touch UIKit framework. Gestouch is very similar in many ways. But I wouldn't call it \"direct port\" because 1) the whole architecture was implemented based just on conference videos and user documentation 2) flash platform is a different platform with own specialization, needs, etc.\nSo I want Gestouch to go far beyond that.\n\nFeatures:\n* Pretty neat architecture! Very similar to Apple's UIGestureRecognizers (Cocoa-Touch UIKit)\n* Works with any display list hierarchy structures: native DisplayList (pure AS3/Flex/your UI framework), Starling or ND2D (Stage3D) and 3D libs...\n* Doesn't require any additional software (may use runtime's build-in touch support)\n* Works across all platforms (where Flash Player or AIR run of course) in exactly same way\n* Extendable. You can write your own application-specific gestures\n* Open-source and free\n\n\n\nh3. Getting Started\n\nAll gestures dispatch (if you listen to!) GestureEvent with the next types:\nGestureEvent.GESTURE_STATE_CHANGE\nGestureEvent.GESTURE_IDLE\nGestureEvent.GESTURE_POSSIBLE\nGestureEvent.GESTURE_FAILED\n\nDiscrete gestures also dispatch:\nGestureEvent.GESTURE_RECOGNIZED\n\nContinuous gestures also dispatch:\nGestureEvent.GESTURE_BEGAN\nGestureEvent.GESTURE_CHANGED\nGestureEvent.GESTURE_ENDED\n\nIf you use a good IDE (such as IntelliJ IDEA, FDT, FlashDevelop, Flash Builder) you should see these events in autocompletion.\n\nQuick start:\n<pre><code>var doubleTap:TapGesture = new TapGesture(myButton);\ndoubleTap.numTapsRequired = 2;\ndoubleTap.addEventListener(GestureEvent.GESTURE_RECOGNIZED, onDoubleTap);\n...\nprivate function onDoubleTap(event:GestureEvent):void\n{\n\t// handle double tap!\n}\n</code></pre>\nor\n<pre><code>var freeTransform:TransformGesture = new TransformGesture(myImage);\nfreeTransform.addEventListener(GestureEvent.GESTURE_BEGAN, onFreeTransform);\nfreeTransform.addEventListener(GestureEvent.GESTURE_CHANGED, onFreeTransform);\n...\nprivate function onFreeTransform(event:GestureEvent):void\n{\n\t// move, rotate, scale — all at once for better performance!\n\ttrace(freeTransform.offsetX, freeTransform.offsetY, freeTransform.rotation, freeTransform.scale);\n}\n</code></pre>\n\n* Check the \"Gestouch Examples\":http://github.com/fljot/GestouchExamples project for a quick jump-in\n* *+Highly recommended+* to watch videos from Apple WWDC conferences as they explain all the concepts and show more or less real-life examples. @see links below\n* \"Introduction video\":http://www.youtube.com/watch?v=NjkmB8rfQjY - my first video, currently outdated\n* TODO: wiki\n\n\n\nh3. Advanced usage: Starling, ...\n\nRecent changes made it possible to work with \"Starling\":http://www.starling-framework.org display list objects as well as any other display list hierarchical structures, e.g. other Stage3D frameworks that have display objects hierarchy like \"ND2D\":https://github.com/nulldesign/nd2d or even 3D libraries.\nIn order to use Gestouch with Starling all you need to do is a bit of bootstrapping:\n<pre><code>starling = new Starling(MyStarlingRootClass, stage);\n/* setup & start your Starling instance here */\n\n// Gestouch initialization step 1 of 3:\n// Initialize native (default) input adapter. Needed for non-DisplayList usage.\nGestouch.inputAdapter ||= new NativeInputAdapter(stage);\n\n// Gestouch initialization step 2 of 3:\n// Register instance of StarlingDisplayListAdapter to be used for objects of type starling.display.DisplayObject.\n// What it does: helps to build hierarchy (chain of parents) for any Starling display object and\n// acts as a adapter for gesture target to provide strong-typed access to methods like globalToLocal() and contains().\nGestouch.addDisplayListAdapter(starling.display.DisplayObject, new StarlingDisplayListAdapter());\n\n// Gestouch initialization step 3 of 3:\n// Initialize and register StarlingTouchHitTester.\n// What it does: finds appropriate target for the new touches (uses Starling Stage#hitTest() method)\n// What does \"-1\" mean: priority for this hit-tester. Since Stage3D layer sits behind native DisplayList\n// we give it lower priority in the sense of interactivity.\nGestouch.addTouchHitTester(new StarlingTouchHitTester(starling), -1);\n// NB! Use Gestouch#removeTouchHitTester() method if you manage multiple Starling instances during\n// your application lifetime.\n</code></pre>\n\nNow you can register gestures as usual:\n<pre><code>var tap:TapGesture = new TapGesture(starlingSprite);</code></pre>\n\n\n\nh3. Roadmap, TODOs\n\n* \"Massive gestures\" & Clusters. For bigger form-factor multitouch usage, when gestures must be a bit less about separate fingers but rather touch clusters (massive multitouch) \n* -Simulator (for testing multitouch gestures without special devices)- With new architecture it must be relatively easy to create SimulatorInputAdapter\n* Chained gestures concept? To transfer touches from one gesture to another. Example: press/hold for circular menu, then drag it around.\n* 3-fingers (3D) gestures (two fingers still, one moving)\n\n\n\nh3. News\n\n* \"Follow me on Twitter\":http://twitter.com/fljot for latest updates\n* Don't forget about \"issues\":https://github.com/fljot/Gestouch/issues section as a good platform for discussions.\n\n\n\nh3. Contribution, Donations\n\nContribute, share. Found it useful, nothing to add? Hire me for some project.\n\n\n\nh3. Links\n\n* \"Gestouch Examples\":http://github.com/fljot/GestouchExamples\n\n* \"Apple WWDC 2011: Making the Most of Multi-Touch on iOS\":https://developer.apple.com/videos/wwdc/2011/?id=118\n* \"Apple WWDC 2010: Simplifying Touch Event Handling with Gesture Recognizers\":https://developer.apple.com/videos/wwdc/2010/?id=120\n* \"Apple WWDC 2010: Advanced Gesture Recognition\":https://developer.apple.com/videos/wwdc/2010/?id=121\n* \"Event Handling Guide for iOS\":https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/\n* \"UIGestureRecognizer Class Reference\":https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizer_Class/\n\n* \"TUIO\":http://www.tuio.org\n\n\nh2. License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "build.template.properties",
    "content": "# IMPORTANT Change to your local system paths before using ANT\n\n# Flex SDK related properties\nFLEX_HOME = path-to-flex-4.5-SDK\nflexSDK.dir = ${FLEX_HOME}\n\nproject.name = ${ant.project.name}\n\n# Project-path relative properties\nsrc.dir = ${basedir}/src\nlibs.dir = ${basedir}/libs\nbinrelease.dir = ${basedir}/bin\nasdoc.dir = ${binrelease.dir}/docs"
  },
  {
    "path": "build.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<project name=\"Gestouch\" default=\"release\" basedir=\".\">\n\n\t<!-- Thanks to Robotlegs project for the tasks -->\n\n\t<!-- Load properties -->\n\t<property file=\"build.properties\" />\n\t<property file=\"version.properties\" />\n\n\n\t<target name=\"release\" description=\"\" depends=\"compile.swc, asdoc, fat.swc\">\n\t\t<!-- TODO: tests? -->\n\t</target>\n\n\t<target name=\"compile.swc\">\n\t\t<echo>[compile] Compiling release SWC</echo>\n\t\t<java jar=\"${flexSDK.dir}/lib/compc.jar\" dir=\"${flexSDK.dir}/frameworks\" fork=\"true\" failonerror=\"true\">\n\t\t\t<!-- Build our SWC with a versioned name. -->\n\t\t\t<arg value=\"-output=${binrelease.dir}/gestouch-${project.version}.swc\"/>\n\t\t\t<!-- We want all the org package classes in the SWC being built. -->\n\t\t\t<arg value=\"-include-sources=${src.dir}\"/>\n\t\t\t<!-- Exclude Flex Framework classes (some mx events comes from binding). -->\n\t\t\t<arg value=\"-external-library-path+=${flexSDK.dir}/frameworks/libs\"/>\n\t\t\t<!-- Exclude any external classes (such as Starling framework classes) -->\n\t\t\t<arg value=\"-external-library-path+=${libs.dir}\"/>\n\t\t\t<!-- Keep the metatags (Apparat?). -->\n\t\t\t<arg value=\"-keep-as3-metadata+=Abstract\"/>\n\t\t\t<!-- Boolean mosh pit! -->\n\t\t\t<arg value=\"-incremental=false\"/>\n\t\t\t<arg value=\"-static-link-runtime-shared-libraries=true\"/>\n\t\t\t<arg value=\"-verbose-stacktraces=true\"/>\n\t\t\t<arg value=\"-headless-server=true\"/>\n\t\t</java>\n\t\t<echo>[compile] Release SWC gestouch-${project.version}.swc created successfully</echo>\n\t</target>\n\n\t<target name=\"asdoc\">\n\t\t<echo>[asdoc] Generating ASDOC documentation</echo>\n\t\t<tstamp>\n\t\t\t<format property=\"docgen.time\" pattern=\"MM/dd/yyyy hh:mm aa\" unit=\"hour\"/>\n\t\t</tstamp>\n\t\t<delete includeemptydirs=\"true\" failonerror=\"false\">\n\t\t\t<fileset dir=\"${asdoc.dir}\" defaultexcludes=\"false\">\n\t\t\t\t<include name=\"**/*\" />\n\t\t\t</fileset>\n\t\t</delete>\n\t\t<java jar=\"${FLEX_HOME}/lib/asdoc.jar\" dir=\"${FLEX_HOME}/frameworks\" fork=\"true\" failonerror=\"true\">\n\t\t\t<arg line=\"-source-path ${src.dir}\"/>\n\t\t\t<arg line=\"-external-library-path+=${libs.dir}\"/>\n\t\t\t<arg line=\"-doc-sources ${src.dir}\"/>\n\t\t\t<arg line=\"-output ${asdoc.dir}\"/>\n\t\t\t<arg value=\"-keep-xml=true\"/>\n\t\t\t<arg value=\"-skip-xsl=true\"/>\n\t\t\t<arg line=\"-window-title 'Gestouch ${project.version}'\"/>\n\t\t\t<arg line=\"-main-title 'Gestouch ${project.version}'\"/>\n\t\t\t<arg line=\"-footer 'Gestouch - http://github.com/fljot/Gestouch/ - Documentation generated at: ${docgen.time}'\"/>\n\t\t\t<arg line=\"-package org.gestouch.gestures 'Gestures'\"/>\n\t\t\t<arg line=\"-package org.gestouch.events 'Gesture events, generated by gesture classes and dispatched by display objects.'\"/>\n\t\t</java>\n\t\t<echo>[asdoc] ASDOC documentation generated successfully</echo>\n\t</target>\n\t\n\t<target name=\"fat.swc\">\n\t\t<echo>[fat.swc] Adding documentation to swc</echo>\n\t\t<!-- updates swc with asdoc xml -->\n\t\t<zip destfile=\"${binrelease.dir}/gestouch-${project.version}.swc\" update=\"true\">\n\t\t\t<zipfileset dir=\"${asdoc.dir}/tempdita\" prefix=\"docs\">\n\t\t\t\t<include name=\"*.*\" />\n\t\t\t\t<exclude name=\"ASDoc_Config.xml\" />\n\t\t\t\t<exclude name=\"overviews.xml\" />\n\t\t\t</zipfileset>\n\t\t</zip>\n\t\t<echo>[fat.swc] Documentation added to swc successfully</echo>\n\t</target>\n\n</project>"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\t\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\t xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<groupId>org.gestouch</groupId>\n\t<artifactId>gestouch</artifactId>\n\t<packaging>swc</packaging>\n\t<version>0.4.7</version>\n\n\t<properties>\n\t\t<flexmojos.version>5.0-beta</flexmojos.version>\n\t\t<flex.sdk.version>4.6.b.23201</flex.sdk.version>\n\t</properties>\n\n\t<!-- Continuous Integration build hosted by CloudBees -->\n\t<ciManagement>\n\t\t<system>jenkins</system>\n\t\t<url>https://fljot.ci.cloudbees.com/job/Gestouch/</url>\n\t</ciManagement>\n\n\t<issueManagement>\n\t\t<system>github</system>\n\t\t<url>https://github.com/fljot/Gestouch/issues</url>\n\t</issueManagement>\n\n\t<!-- GitHub Software Configuration Management -->\n\t<scm>\n\t\t<url>https://github.com/fljot/Gestouch</url>\n\t\t<connection>scm:git:ssh://git@github.com:fljot/Gestouch.git</connection>\n\t\t<developerConnection>scm:git:ssh://git@github.com:fljot/Gestouch.git</developerConnection>\n\t</scm>\n\n\t<build>\n\t\t<sourceDirectory>src/</sourceDirectory>\n\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>net.flexmojos.oss</groupId>\n\t\t\t\t<artifactId>flexmojos-maven-plugin</artifactId>\n\t\t\t\t<version>${flexmojos.version}</version>\n\t\t\t\t<extensions>true</extensions>\n\t\t\t\t<configuration>\n\t\t\t\t\t<debug>true</debug>\n\t\t\t\t\t<storepass/>\n\t\t\t\t\t<skipTests>true</skipTests>\n\t\t\t\t\t<skipTest>true</skipTest>\n\t\t\t\t\t<debug>true</debug>\n\t\t\t\t\t<verboseStacktraces>true</verboseStacktraces>\n\t\t\t\t\t<!--\n\t\t\t\t\tNB! SWC is compiled in debug mode with verbose stacktraces\n\t\t\t\t\tfor better development process.\n\t\t\t\t\tIt's okay and will not affect application performance\n\t\t\t\t\tUNLESS you are using this library as RSL.\n\t\t\t\t\t-->\n\t\t\t\t\t<keepAs3Metadatas>\n\t\t\t\t\t\t<!-- potentially for Apparat. probably useless -->\n\t\t\t\t\t\t<keepAs3Metadata>Abstract</keepAs3Metadata>\n\t\t\t\t\t</keepAs3Metadatas>\n\t\t\t\t</configuration>\n\t\t\t\t<dependencies>\n\t\t\t\t\t<dependency>\n\t\t\t\t\t\t<groupId>com.adobe.flex</groupId>\n\t\t\t\t\t\t<artifactId>compiler</artifactId>\n\t\t\t\t\t\t<version>${flex.sdk.version}</version>\n\t\t\t\t\t\t<type>pom</type>\n\t\t\t\t\t</dependency>\n\t\t\t\t</dependencies>\n\t\t\t</plugin>\n\n\t\t\t<plugin>\n\t\t\t\t<groupId>net.flexmojos.oss</groupId>\n\t\t\t\t<artifactId>flexmojos-maven-plugin</artifactId>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<phase>prepare-package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>asdoc</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t\t<configuration>\n\t\t\t\t\t<storepass/>\n\t\t\t\t\t<keepXml>true</keepXml>\n\t\t\t\t\t<skipXsl>true</skipXsl>\n\t\t\t\t\t<windowTitle>Gestouch ${project.version}</windowTitle>\n\t\t\t\t\t<mainTitle>Gestouch ${project.version}</mainTitle>\n\t\t\t\t\t<footer>Gestouch - http://github.com/fljot/Gestouch/ - Documentation generated at: ${maven.build.timestamp}</footer>\n\t\t\t\t</configuration>\n\t\t\t</plugin>\n\n\t\t\t<plugin>\n\t\t\t\t<artifactId>maven-antrun-plugin</artifactId>\n\t\t\t\t<version>1.7</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>fail-to-deploy-in-develop</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<target>\n\t\t\t\t\t\t\t\t<zip destfile=\"${project.build.directory}/${project.artifactId}-${project.version}.swc\" update=\"true\">\n\t\t\t\t\t\t\t\t\t<zipfileset dir=\"${project.build.directory}/asdoc/tempdita\" prefix=\"docs\">\n\t\t\t\t\t\t\t\t\t\t<include name=\"*.*\"/>\n\t\t\t\t\t\t\t\t\t\t<exclude name=\"ASDoc_Config.xml\"/>\n\t\t\t\t\t\t\t\t\t\t<exclude name=\"overviews.xml\"/>\n\t\t\t\t\t\t\t\t\t</zipfileset>\n\t\t\t\t\t\t\t\t</zip>\n\t\t\t\t\t\t\t</target>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>run</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\n\t\t\t<!-- I don't think I need this as I put documentation into original SWC -->\n\t\t\t<!--\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.codehaus.mojo</groupId>\n\t\t\t\t<artifactId>build-helper-maven-plugin</artifactId>\n\t\t\t\t<version>1.3</version>\n\t\t\t\t<executions>\n\t\t\t\t\t<execution>\n\t\t\t\t\t\t<id>attach-artifacts</id>\n\t\t\t\t\t\t<phase>package</phase>\n\t\t\t\t\t\t<goals>\n\t\t\t\t\t\t\t<goal>attach-artifact</goal>\n\t\t\t\t\t\t</goals>\n\t\t\t\t\t\t<configuration>\n\t\t\t\t\t\t\t<artifacts>\n\t\t\t\t\t\t\t\t<artifact>\n\t\t\t\t\t\t\t\t\t<file>${project.build.directory}/${project.artifactId}-fat-${project.version}.swc</file>\n\t\t\t\t\t\t\t\t\t<type>swc</type>\n\t\t\t\t\t\t\t\t\t<classifier>fat</classifier>\n\t\t\t\t\t\t\t\t</artifact>\n\t\t\t\t\t\t\t</artifacts>\n\t\t\t\t\t\t</configuration>\n\t\t\t\t\t</execution>\n\t\t\t\t</executions>\n\t\t\t</plugin>\n\t\t\t-->\n\t\t</plugins>\n\n\t</build>\n\n\t<reporting>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.sonatype.flexmojos</groupId>\n\t\t\t\t<artifactId>flexmojos-maven-plugin</artifactId>\n\t\t\t\t<version>${flexmojos.version}</version>\n\t\t\t\t<reportSets>\n\t\t\t\t\t<reportSet>\n\t\t\t\t\t\t<id>flex-reports</id>\n\t\t\t\t\t\t<reports>\n\t\t\t\t\t\t\t<report>asdoc-report</report>\n\t\t\t\t\t\t</reports>\n\t\t\t\t\t</reportSet>\n\t\t\t\t</reportSets>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</reporting>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>com.adobe.flex</groupId>\n\t\t\t<artifactId>compiler</artifactId>\n\t\t\t<version>${flex.sdk.version}</version>\n\t\t\t<type>pom</type>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.adobe.flex.framework</groupId>\n\t\t\t<artifactId>flex-framework</artifactId>\n\t\t\t<version>${flex.sdk.version}</version>\n\t\t\t<type>pom</type>\n\t\t\t<scope>provided</scope>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>com.gamua</groupId>\n\t\t\t<artifactId>starling-framework</artifactId>\n\t\t\t<version>[1.1,]</version>\n\t\t\t<type>swc</type>\n\t\t</dependency>\n\t</dependencies>\n\n\t<repositories>\n\t\t<repository>\n\t\t\t<id>flex-mojos-repository</id>\n\t\t\t<url>http://repository.sonatype.org/content/groups/flexgroup</url>\n\t\t</repository>\n\n\t\t<repository>\n\t\t\t<id>starling-repository</id>\n\t\t\t<url>http://repository-trylogic.forge.cloudbees.com/snapshot</url>\n\t\t\t<releases>\n\t\t\t\t<enabled>false</enabled>\n\t\t\t</releases>\n\t\t\t<snapshots>\n\t\t\t\t<enabled>true</enabled>\n\t\t\t</snapshots>\n\t\t</repository>\n\t</repositories>\n\n\t<pluginRepositories>\n\t\t<pluginRepository>\n\t\t\t<id>flex-mojos-plugin-repository</id>\n\t\t\t<url>http://repository.sonatype.org/content/groups/flexgroup</url>\n\t\t\t<releases>\n\t\t\t\t<enabled>true</enabled>\n\t\t\t\t<updatePolicy>never</updatePolicy>\n\t\t\t</releases>\n\t\t\t<snapshots>\n\t\t\t\t<enabled>false</enabled>\n\t\t\t\t<updatePolicy>never</updatePolicy>\n\t\t\t</snapshots>\n\t\t</pluginRepository>\n\t</pluginRepositories>\n\n\t<developers>\n\t\t<developer>\n\t\t\t<name>Pavel fljōt Pevnitskiy</name>\n\t\t\t<email>pavel.fljot at gmail.com</email>\n\t\t</developer>\n\t</developers>\n</project>\n"
  },
  {
    "path": "src/org/gestouch/core/Gestouch.as",
    "content": "package org.gestouch.core\n{\n\timport flash.display.DisplayObject;\n\timport flash.utils.Dictionary;\n\timport flash.utils.getQualifiedClassName;\n\n\timport org.gestouch.extensions.native.NativeDisplayListAdapter;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tfinal public class Gestouch\n\t{\n\t\tprivate static const _displayListAdaptersMap:Dictionary = new Dictionary();\n\t\t\n\t\t\n\t\t/** @private */\n\t\tprivate static var _inputAdapter:IInputAdapter;\n\t\t\n\t\t/**\n\t\t * \n\t\t */\n\t\tpublic static function get inputAdapter():IInputAdapter\n\t\t{\n\t\t\treturn _inputAdapter;\n\t\t}\n\t\tpublic static function set inputAdapter(value:IInputAdapter):void\n\t\t{\n\t\t\tif (_inputAdapter == value)\n\t\t\t\treturn;\n\t\t\t\n\t\t\t_inputAdapter = value;\n\t\t\tif (inputAdapter)\n\t\t\t{\n\t\t\t\tinputAdapter.touchesManager = touchesManager;\n\t\t\t\tinputAdapter.init();\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprivate static var _touchesManager:TouchesManager;\n\t\t/**\n\t\t * \n\t\t */\n\t\tpublic static function get touchesManager():TouchesManager\n\t\t{\n\t\t\treturn _touchesManager ||= new TouchesManager(gesturesManager);\n\t\t}\n\t\t\n\t\t\n\t\tprivate static var _gesturesManager:GesturesManager;\n\t\tpublic static function get gesturesManager():GesturesManager\n\t\t{\n\t\t\treturn _gesturesManager ||= new GesturesManager();\n\t\t}\n\t\t\n\t\t\n\t\tpublic static function addDisplayListAdapter(targetClass:Class, adapter:IDisplayListAdapter):void\n\t\t{\n\t\t\tif (!targetClass || !adapter)\n\t\t\t{\n\t\t\t\tthrow new Error(\"Argument error: both arguments required.\");\n\t\t\t}\n\t\t\t\n\t\t\t_displayListAdaptersMap[targetClass] = adapter;\n\t\t}\n\t\t\n\t\t\n\t\tpublic static function addTouchHitTester(hitTester:ITouchHitTester, priority:int = 0):void\n\t\t{\n\t\t\ttouchesManager.gestouch_internal::addTouchHitTester(hitTester, priority);\n\t\t}\n\t\t\n\t\t\n\t\tpublic static function removeTouchHitTester(hitTester:ITouchHitTester):void\n\t\t{\n\t\t\ttouchesManager.gestouch_internal::removeInputAdapter(hitTester);\n\t\t}\n\t\t\n\t\t\n//\t\tpublic static function getTouches(target:Object = null):Array\n//\t\t{\n//\t\t\treturn touchesManager.getTouches(target);\n//\t\t}\n\t\t\n\t\tgestouch_internal static function createGestureTargetAdapter(target:Object):IDisplayListAdapter\n\t\t{\n\t\t\tvar adapter:IDisplayListAdapter = Gestouch.gestouch_internal::getDisplayListAdapter(target);\n\n\t\t\t// Lazy add display list adapter for flash.display::DisplayObject\n\t\t\tif (!adapter && target is flash.display.DisplayObject)\n\t\t\t{\n\t\t\t\tadapter = new NativeDisplayListAdapter();\n\t\t\t\tGestouch.addDisplayListAdapter(DisplayObject, adapter);\n\t\t\t}\n\n\t\t\tif (adapter)\n\t\t\t{\n\t\t\t\treturn new (adapter.reflect())(target);\n\t\t\t}\n\t\t\t\n\t\t\tthrow new Error(\"Cannot create adapter for target \" + target + \" of type \" + getQualifiedClassName(target) + \".\");\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal static function getDisplayListAdapter(object:Object):IDisplayListAdapter\n\t\t{\n\t\t\tfor (var key:Object in _displayListAdaptersMap)\n\t\t\t{\n\t\t\t\tvar targetClass:Class = key as Class;\n\t\t\t\tif (object is targetClass)\n\t\t\t\t{\n\t\t\t\t\treturn _displayListAdaptersMap[key] as IDisplayListAdapter;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/core/GestureState.as",
    "content": "package org.gestouch.core\n{\n\timport flash.utils.Dictionary;\n\timport flash.errors.IllegalOperationError;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tfinal public class GestureState\n\t{\n\t\tpublic static const POSSIBLE:GestureState = new GestureState(\"POSSIBLE\");\n\t\tpublic static const RECOGNIZED:GestureState = new GestureState(\"RECOGNIZED\", true);\n\t\tpublic static const BEGAN:GestureState = new GestureState(\"BEGAN\");\n\t\tpublic static const CHANGED:GestureState = new GestureState(\"CHANGED\");\n\t\tpublic static const ENDED:GestureState = new GestureState(\"ENDED\", true);\n\t\tpublic static const CANCELLED:GestureState = new GestureState(\"CANCELLED\", true);\n\t\tpublic static const FAILED:GestureState = new GestureState(\"FAILED\", true);\n\t\t\n\t\tprivate static var allStatesInitialized:Boolean;\n\t\t\n\t\t\n\t\tprivate var name:String;\n\t\tprivate var eventType:String;\n\t\tprivate var validTransitionStateMap:Dictionary = new Dictionary();\n\t\t\n\t\t{\n\t\t\t_initClass();\n\t\t}\n\t\t\n\t\t\n\t\tpublic function GestureState(name:String, isEndState:Boolean = false)\n\t\t{\n\t\t\tif (allStatesInitialized)\n\t\t\t{\n\t\t\t\tthrow new IllegalOperationError(\"You cannot create gesture states.\" +\n\t\t\t\t\"Use predefined constats like GestureState.RECOGNIZED\");\n\t\t\t}\n\t\t\t\n\t\t\tthis.name = \"GestureState.\" + name;\n\t\t\tthis.eventType = \"gesture\" + name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();\n\t\t\tthis._isEndState = isEndState;\n\t\t}\n\t\t\n\t\t\n\t\tprivate static function _initClass():void\n\t\t{\n\t\t\tPOSSIBLE.setValidNextStates(RECOGNIZED, BEGAN, FAILED);\n\t\t\tRECOGNIZED.setValidNextStates(POSSIBLE);\n\t\t\tBEGAN.setValidNextStates(CHANGED, ENDED, CANCELLED);\n\t\t\tCHANGED.setValidNextStates(CHANGED, ENDED, CANCELLED);\n\t\t\tENDED.setValidNextStates(POSSIBLE);\n\t\t\tFAILED.setValidNextStates(POSSIBLE);\n\t\t\tCANCELLED.setValidNextStates(POSSIBLE);\n\t\t\t\n\t\t\tallStatesInitialized = true;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function toString():String\n\t\t{\n\t\t\treturn name;\n\t\t}\n\t\t\n\t\t\n\t\tprivate function setValidNextStates(...states):void\n\t\t{\n\t\t\tfor each (var state:GestureState in states)\n\t\t\t{\n\t\t\t\tvalidTransitionStateMap[state] = true;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function toEventType():String\n\t\t{\n\t\t\treturn eventType;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function canTransitionTo(state:GestureState):Boolean\n\t\t{\n\t\t\treturn (state in validTransitionStateMap);\n\t\t}\n\t\t\n\t\t\n\t\tprivate var _isEndState:Boolean = false;\n\t\tgestouch_internal function get isEndState():Boolean\n\t\t{\n\t\t\treturn _isEndState;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/core/GesturesManager.as",
    "content": "package org.gestouch.core\n{\n\timport flash.display.DisplayObject;\n\timport flash.display.Shape;\n\timport flash.display.Stage;\n\timport flash.errors.IllegalOperationError;\n\timport flash.events.Event;\n\timport flash.events.IEventDispatcher;\n\timport flash.utils.Dictionary;\n\timport flash.utils.getQualifiedClassName;\n\n\timport org.gestouch.extensions.native.NativeTouchHitTester;\n\timport org.gestouch.gestures.Gesture;\n\timport org.gestouch.input.NativeInputAdapter;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class GesturesManager\n\t{\n\t\tprotected const _frameTickerShape:Shape = new Shape();\n\t\tprotected var _gesturesMap:Dictionary = new Dictionary(true);\n\t\tprotected var _gesturesForTouchMap:Dictionary = new Dictionary();\n\t\tprotected var _gesturesForTargetMap:Dictionary = new Dictionary(true);\n\t\tprotected var _dirtyGesturesCount:uint = 0;\n\t\tprotected var _dirtyGesturesMap:Dictionary = new Dictionary(true);\n\t\tprotected var _stage:Stage;\n\t\t\n\t\tuse namespace gestouch_internal;\n\t\t\n\t\t\n\t\tpublic function GesturesManager()\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Private methods\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function onStageAvailable(stage:Stage):void\n\t\t{\n\t\t\t_stage = stage;\n\t\t\t\n\t\t\tGestouch.inputAdapter ||= new NativeInputAdapter(stage);\n\t\t\tGestouch.addTouchHitTester(new NativeTouchHitTester(stage));\n\t\t}\n\t\t\n\t\t\n\t\tprotected function resetDirtyGestures():void\n\t\t{\n\t\t\tfor (var gesture:Object in _dirtyGesturesMap)\n\t\t\t{\n\t\t\t\t(gesture as Gesture).reset();\n\t\t\t}\n\t\t\t_dirtyGesturesCount = 0;\n\t\t\t_dirtyGesturesMap = new Dictionary(true);\n\t\t\t_frameTickerShape.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function addGesture(gesture:Gesture):void\n\t\t{\n\t\t\tif (!gesture)\n\t\t\t{\n\t\t\t\tthrow new ArgumentError(\"Argument 'gesture' must be not null.\");\n\t\t\t}\n\t\t\t\n\t\t\tconst target:Object = gesture.target;\n\t\t\tif (!target)\n\t\t\t{\n\t\t\t\tthrow new IllegalOperationError(\"Gesture must have target.\");\n\t\t\t}\n\t\t\t\n\t\t\tvar targetGestures:Vector.<Gesture> = _gesturesForTargetMap[target] as Vector.<Gesture>;\n\t\t\tif (targetGestures)\n\t\t\t{\n\t\t\t\tif (targetGestures.indexOf(gesture) == -1)\n\t\t\t\t{\n\t\t\t\t\ttargetGestures.push(gesture);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttargetGestures = _gesturesForTargetMap[target] = new Vector.<Gesture>();\n\t\t\t\ttargetGestures[0] = gesture;\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t_gesturesMap[gesture] = true;\n\t\t\t\n\t\t\tif (!_stage)\n\t\t\t{\n\t\t\t\tvar targetAsDO:DisplayObject = target as DisplayObject;\n\t\t\t\tif (targetAsDO)\n\t\t\t\t{\n\t\t\t\t\tif (targetAsDO.stage)\n\t\t\t\t\t{\n\t\t\t\t\t\tonStageAvailable(targetAsDO.stage);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttargetAsDO.addEventListener(Event.ADDED_TO_STAGE, gestureTarget_addedToStageHandler, false,0, true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function removeGesture(gesture:Gesture):void\n\t\t{\n\t\t\tif (!gesture)\n\t\t\t{\n\t\t\t\tthrow new ArgumentError(\"Argument 'gesture' must be not null.\");\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\tvar target:Object = gesture.target;\n\t\t\t// check for target because it could be already GC-ed (since target reference is weak)\n\t\t\tif (target)\n\t\t\t{\n\t\t\t\tvar targetGestures:Vector.<Gesture> = _gesturesForTargetMap[target] as Vector.<Gesture>;\n\t\t\t\tif (targetGestures.length > 1)\n\t\t\t\t{\n\t\t\t\t\ttargetGestures.splice(targetGestures.indexOf(gesture), 1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdelete _gesturesForTargetMap[target];\n\t\t\t\t\tif (target is IEventDispatcher)\n\t\t\t\t\t{\n\t\t\t\t\t\t(target as IEventDispatcher).removeEventListener(Event.ADDED_TO_STAGE, gestureTarget_addedToStageHandler);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tdelete _gesturesMap[gesture];\n\t\t\t\n\t\t\tgesture.reset();\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function scheduleGestureStateReset(gesture:Gesture):void\n\t\t{\n\t\t\tif (!_dirtyGesturesMap[gesture])\n\t\t\t{\n\t\t\t\t_dirtyGesturesMap[gesture] = true;\n\t\t\t\t_dirtyGesturesCount++;\n\t\t\t\t_frameTickerShape.addEventListener(Event.ENTER_FRAME, enterFrameHandler);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onGestureRecognized(gesture:Gesture):void\n\t\t{\n\t\t\tconst target:Object = gesture.target;\n\t\t\t\n\t\t\tfor (var key:Object in _gesturesMap)\n\t\t\t{\n\t\t\t\tvar otherGesture:Gesture = key as Gesture;\n\t\t\t\tvar otherTarget:Object = otherGesture.target;\n\t\t\t\t\n\t\t\t\t// conditions for otherGesture \"own properties\"\n\t\t\t\tif (otherGesture != gesture &&\n\t\t\t\t\ttarget && otherTarget &&//in case GC worked half way through\n\t\t\t\t\totherGesture.enabled &&\n\t\t\t\t\totherGesture.state == GestureState.POSSIBLE)\n\t\t\t\t{\n\t\t\t\t\tif (otherTarget == target ||\n\t\t\t\t\t\tgesture.targetAdapter.contains(otherTarget) ||\n\t\t\t\t\t\totherGesture.targetAdapter.contains(target)\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// conditions for gestures relations\n\t\t\t\t\t\tif (gesture.canPreventGesture(otherGesture) &&\n\t\t\t\t\t\t\totherGesture.canBePreventedByGesture(gesture) &&\n\t\t\t\t\t\t\t(gesture.gesturesShouldRecognizeSimultaneouslyCallback == null ||\n\t\t\t\t\t\t\t !gesture.gesturesShouldRecognizeSimultaneouslyCallback(gesture, otherGesture)) &&\n\t\t\t\t\t\t\t(otherGesture.gesturesShouldRecognizeSimultaneouslyCallback == null ||\n\t\t\t\t\t\t\t !otherGesture.gesturesShouldRecognizeSimultaneouslyCallback(otherGesture, gesture)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\totherGesture.setState_internal(GestureState.FAILED);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tvar gesture:Gesture;\n\t\t\tvar i:uint;\n\t\t\t\n\t\t\t// This vector will contain active gestures for specific touch during all touch session.\n\t\t\tvar gesturesForTouch:Vector.<Gesture> = _gesturesForTouchMap[touch] as Vector.<Gesture>;\n\t\t\tif (!gesturesForTouch)\n\t\t\t{\n\t\t\t\tgesturesForTouch = new Vector.<Gesture>();\n\t\t\t\t_gesturesForTouchMap[touch] = gesturesForTouch;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// touch object may be pooled in the future\n\t\t\t\tgesturesForTouch.length = 0;\n\t\t\t}\n\t\t\t\n\t\t\tvar target:Object = touch.target;\n\t\t\tconst displayListAdapter:IDisplayListAdapter = Gestouch.gestouch_internal::getDisplayListAdapter(target);\n\t\t\tif (!displayListAdapter)\n\t\t\t{\n\t\t\t\tthrow new Error(\"Display list adapter not found for target of type '\" + getQualifiedClassName(target) + \"'.\");\n\t\t\t}\n\t\t\tconst hierarchy:Vector.<Object> = displayListAdapter.getHierarchy(target);\n\t\t\tconst hierarchyLength:uint = hierarchy.length;\n\t\t\tif (hierarchyLength == 0)\n\t\t\t{\n\t\t\t\tthrow new Error(\"No hierarchy build for target '\" + target +\"'. Something is wrong with that IDisplayListAdapter.\");\n\t\t\t}\n\t\t\tif (_stage && !(hierarchy[hierarchyLength - 1] is Stage))\n\t\t\t{\n\t\t\t\t// Looks like some non-native (non DisplayList) hierarchy\n\t\t\t\t// but we must always handle gestures with Stage target\n\t\t\t\t// since Stage is anyway the top-most parent\n\t\t\t\thierarchy[hierarchyLength] = _stage;\n\t\t\t}\n\t\t\t\n\t\t\t// Create a sorted(!) list of gestures which are interested in this touch.\n\t\t\t// Sorting priority: deeper target has higher priority, recently added gesture has higher priority.\n\t\t\tvar gesturesForTarget:Vector.<Gesture>;\n\t\t\tfor each (target in hierarchy)\n\t\t\t{\n\t\t\t\tgesturesForTarget = _gesturesForTargetMap[target] as Vector.<Gesture>;\n\t\t\t\tif (gesturesForTarget)\n\t\t\t\t{\n\t\t\t\t\ti = gesturesForTarget.length;\n\t\t\t\t\twhile (i-- > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tgesture = gesturesForTarget[i];\n\t\t\t\t\t\tif (gesture.enabled &&\n\t\t\t\t\t\t\t(gesture.gestureShouldReceiveTouchCallback == null ||\n\t\t\t\t\t\t\t gesture.gestureShouldReceiveTouchCallback(gesture, touch)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t//TODO: optimize performance! decide between unshift() vs [i++] = gesture + reverse()\n\t\t\t\t\t\t\tgesturesForTouch.unshift(gesture);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// Then we populate them with this touch and event.\n\t\t\t// They might start tracking this touch or ignore it (via Gesture#ignoreTouch())\n\t\t\ti = gesturesForTouch.length;\n\t\t\twhile (i-- > 0)\n\t\t\t{\n\t\t\t\tgesture = gesturesForTouch[i];\n\t\t\t\t// Check for state because previous (i+1) gesture may already abort current (i) one\n\t\t\t\tif (!_dirtyGesturesMap[gesture])\n\t\t\t\t{\n\t\t\t\t\tgesture.touchBeginHandler(touch);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tgesturesForTouch.splice(i, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tvar gesturesForTouch:Vector.<Gesture> = _gesturesForTouchMap[touch] as Vector.<Gesture>;\n\t\t\tvar gesture:Gesture;\n\t\t\tvar i:uint = gesturesForTouch.length;\n\t\t\twhile (i-- > 0)\n\t\t\t{\n\t\t\t\tgesture = gesturesForTouch[i];\n\t\t\t\t\n\t\t\t\tif (!_dirtyGesturesMap[gesture] && gesture.isTrackingTouch(touch.id))\n\t\t\t\t{\n\t\t\t\t\tgesture.touchMoveHandler(touch);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// gesture is no more interested in this touch (e.g. ignoreTouch was called)\n\t\t\t\t\tgesturesForTouch.splice(i, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tvar gesturesForTouch:Vector.<Gesture> = _gesturesForTouchMap[touch] as Vector.<Gesture>;\n\t\t\tvar gesture:Gesture;\n\t\t\tvar i:uint = gesturesForTouch.length;\n\t\t\twhile (i-- > 0)\n\t\t\t{\n\t\t\t\tgesture = gesturesForTouch[i];\n\t\t\t\t\n\t\t\t\tif (!_dirtyGesturesMap[gesture] && gesture.isTrackingTouch(touch.id))\n\t\t\t\t{\n\t\t\t\t\tgesture.touchEndHandler(touch);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tgesturesForTouch.length = 0;// release for GC\n\t\t\t\n\t\t\tdelete _gesturesForTouchMap[touch];//TODO: remove this once Touch objects are pooled\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchCancel(touch:Touch):void\n\t\t{\n\t\t\tvar gesturesForTouch:Vector.<Gesture> = _gesturesForTouchMap[touch] as Vector.<Gesture>;\n\t\t\tvar gesture:Gesture;\n\t\t\tvar i:uint = gesturesForTouch.length;\n\t\t\twhile (i-- > 0)\n\t\t\t{\n\t\t\t\tgesture = gesturesForTouch[i];\n\t\t\t\t\n\t\t\t\tif (!_dirtyGesturesMap[gesture] && gesture.isTrackingTouch(touch.id))\n\t\t\t\t{\n\t\t\t\t\tgesture.touchCancelHandler(touch);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tgesturesForTouch.length = 0;// release for GC\n\t\t\t\n\t\t\tdelete _gesturesForTouchMap[touch];//TODO: remove this once Touch objects are pooled\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Event handlers\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function gestureTarget_addedToStageHandler(event:Event):void\n\t\t{\n\t\t\tvar target:DisplayObject = event.target as DisplayObject;\n\t\t\ttarget.removeEventListener(Event.ADDED_TO_STAGE, gestureTarget_addedToStageHandler);\n\t\t\tif (!_stage)\n\t\t\t{\n\t\t\t\tonStageAvailable(target.stage);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprivate function enterFrameHandler(event:Event):void\n\t\t{\n\t\t\tresetDirtyGestures();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/core/IDisplayListAdapter.as",
    "content": "package org.gestouch.core\n{\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic interface IDisplayListAdapter extends IGestureTargetAdapter\n\t{\n\t\tfunction getHierarchy(target:Object):Vector.<Object>;\n\t\t\n\t\tfunction reflect():Class;\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/core/IGestureTargetAdapter.as",
    "content": "package org.gestouch.core\n{\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic interface IGestureTargetAdapter\n\t{\n\t\tfunction get target():Object;\n\t\t\n\t\tfunction contains(object:Object):Boolean;\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/core/IInputAdapter.as",
    "content": "package org.gestouch.core\n{\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic interface IInputAdapter\n\t{\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tfunction set touchesManager(value:TouchesManager):void;\n\t\t\n\t\t/**\n\t\t * Called when input adapter is set.\n\t\t */\n\t\tfunction init():void;\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/core/ITouchHitTester.as",
    "content": "package org.gestouch.core\n{\n\timport flash.geom.Point;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic interface ITouchHitTester\n\t{\n\t\tfunction hitTest(point:Point, possibleTarget:Object = null):Object;\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/core/Touch.as",
    "content": "package org.gestouch.core\n{\n\timport flash.geom.Point;\n\n\n\t/**\n\t * TODO:\n\t * - maybe add \"phase\" (began, moved, stationary, ended)?\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class Touch\n\t{\n\t\t/**\n\t\t * Touch point ID.\n\t\t */\n\t\tpublic var id:uint;\n\t\t/**\n\t\t * The original event target for this touch (touch began with).\n\t\t */\n\t\tpublic var target:Object;\n\t\t\n\t\tpublic var sizeX:Number;\n\t\tpublic var sizeY:Number;\n\t\tpublic var pressure:Number;\n\t\t\n//\t\tpublic var lastMove:Point;\n\n\t\tuse namespace gestouch_internal;\n\t\t\n\t\t\n\t\tpublic function Touch(id:uint = 0)\n\t\t{\n\t\t\tthis.id = id;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _location:Point;\n\t\tpublic function get location():Point\n\t\t{\n\t\t\treturn _location.clone();\n\t\t}\n\t\tgestouch_internal function setLocation(x:Number, y:Number, time:uint):void\n\t\t{\n\t\t\t_location = new Point(x, y);\n\t\t\t_beginLocation = _location.clone();\n\t\t\t_previousLocation = _location.clone();\n\t\t\t\n\t\t\t_time = time;\n\t\t\t_beginTime = time;\n\t\t}\n\t\tgestouch_internal function updateLocation(x:Number, y:Number, time:uint):Boolean\n\t\t{\n\t\t\tif (_location)\n\t\t\t{\n\t\t\t\tif (_location.x == x && _location.y == y)\n\t\t\t\t\treturn false;\n\t\t\t\t\n\t\t\t\t_previousLocation.x = _location.x;\n\t\t\t\t_previousLocation.y = _location.y;\n\t\t\t\t_location.x = x;\n\t\t\t\t_location.y = y;\n\t\t\t\t_time = time;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsetLocation(x, y, time);\n\t\t\t}\n\t\t\t\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _previousLocation:Point;\n\t\tpublic function get previousLocation():Point\n\t\t{\n\t\t\treturn _previousLocation.clone();\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _beginLocation:Point;\n\t\tpublic function get beginLocation():Point\n\t\t{\n\t\t\treturn _beginLocation.clone();\n\t\t}\n\t\t\n\t\t\n\t\tpublic function get locationOffset():Point\n\t\t{\n\t\t\treturn _location.subtract(_beginLocation);\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _time:uint;\n\t\tpublic function get time():uint\n\t\t{\n\t\t\treturn _time;\n\t\t}\n\t\tgestouch_internal function setTime(value:uint):void\n\t\t{\n\t\t\t_time = value;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _beginTime:uint;\n\t\tpublic function get beginTime():uint\n\t\t{\n\t\t\treturn _beginTime;\n\t\t}\n\t\tgestouch_internal function setBeginTime(value:uint):void\n\t\t{\n\t\t\t_beginTime = value;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function clone():Touch\n\t\t{\n\t\t\tvar touch:Touch = new Touch(id);\n\t\t\ttouch._location = _location.clone();\n\t\t\ttouch._beginLocation = _beginLocation.clone();\n\t\t\ttouch.target = target;\n\t\t\ttouch.sizeX = sizeX;\n\t\t\ttouch.sizeY = sizeY;\n\t\t\ttouch.pressure = pressure;\n\t\t\ttouch._time = _time;\n\t\t\ttouch._beginTime = _beginTime;\n\t\t\t\n\t\t\treturn touch;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function toString():String\n\t\t{\n\t\t\treturn \"Touch [id: \" + id + \", location: \" + location + \", ...]\";\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/core/TouchesManager.as",
    "content": "package org.gestouch.core\n{\n\timport flash.display.Stage;\n\timport flash.geom.Point;\n\timport flash.utils.Dictionary;\n\timport flash.utils.getTimer;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class TouchesManager\n\t{\n\t\tprotected var _gesturesManager:GesturesManager;\n\t\tprotected var _touchesMap:Object = {};\n\t\tprotected var _hitTesters:Vector.<ITouchHitTester> = new Vector.<ITouchHitTester>();\n\t\tprotected var _hitTesterPrioritiesMap:Dictionary = new Dictionary(true);\n\t\t\n\t\tuse namespace gestouch_internal;\n\t\t\n\t\t\n\t\tpublic function TouchesManager(gesturesManager:GesturesManager)\n\t\t{\n\t\t\t_gesturesManager = gesturesManager;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _activeTouchesCount:uint;\n\t\tpublic function get activeTouchesCount():uint\n\t\t{\n\t\t\treturn _activeTouchesCount;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function getTouches(target:Object = null):Array\n\t\t{\n\t\t\tconst touches:Array = [];\n\t\t\tif (!target || target is Stage)\n\t\t\t{\n\t\t\t\t// return all touches\n\t\t\t\tvar i:uint = 0;\n\t\t\t\tfor each (var touch:Touch in _touchesMap)\n\t\t\t\t{\n\t\t\t\t\ttouches[i++] = touch;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t//TODO\n\t\t\t}\n\t\t\t\n\t\t\treturn touches;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function addTouchHitTester(touchHitTester:ITouchHitTester, priority:int = 0):void\n\t\t{\n\t\t\tif (!touchHitTester)\n\t\t\t{\n\t\t\t\tthrow new ArgumentError(\"Argument must be non null.\");\n\t\t\t}\n\t\t\t\n\t\t\tif (_hitTesters.indexOf(touchHitTester) == -1)\n\t\t\t{\n\t\t\t\t_hitTesters.push(touchHitTester);\n\t\t\t}\n\t\t\t\n\t\t\t_hitTesterPrioritiesMap[touchHitTester] = priority;\n\t\t\t// Sort hit testers using their priorities\n\t\t\t_hitTesters.sort(hitTestersSorter);\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function removeInputAdapter(touchHitTester:ITouchHitTester):void\n\t\t{\n\t\t\tif (!touchHitTester)\n\t\t\t{\n\t\t\t\tthrow new ArgumentError(\"Argument must be non null.\");\n\t\t\t}\n\t\t\t\n\t\t\tvar index:int = _hitTesters.indexOf(touchHitTester);\n\t\t\tif (index == -1)\n\t\t\t{\n\t\t\t\tthrow new Error(\"This touchHitTester is not registered.\");\n\t\t\t}\n\t\t\t\n\t\t\t_hitTesters.splice(index, 1);\n\t\t\tdelete _hitTesterPrioritiesMap[touchHitTester];\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchBegin(touchID:uint, x:Number, y:Number, possibleTarget:Object = null):Boolean\n\t\t{\n\t\t\tif (touchID in _touchesMap)\n\t\t\t\treturn false;// touch with specified ID is already registered and being tracked\n\t\t\t\n\t\t\tconst location:Point = new Point(x, y);\n\t\t\t\n\t\t\tfor each (var registeredTouch:Touch in _touchesMap)\n\t\t\t{\n\t\t\t\t// Check if touch at the same location exists.\n\t\t\t\t// In case we listen to both TouchEvents and MouseEvents, one of them will come first\n\t\t\t\t// (right now looks like MouseEvent dispatched first, but who know what Adobe will\n\t\t\t\t// do tomorrow). This check helps to filter out the one comes after.\n\t\t\t\t\n\t\t\t\t// NB! According to the tests with some IR multitouch frame and Windows computer\n\t\t\t\t// TouchEvent comes first, but the following MouseEvent has slightly offset location\n\t\t\t\t// (1px both axis). That is why Point#distance() used instead of Point#equals()\n\t\t\t\t\n\t\t\t\tif (Point.distance(registeredTouch.location, location) < 2)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\t\n\t\t\tconst touch:Touch = createTouch();\n\t\t\ttouch.id = touchID;\n\t\t\t\n\t\t\tvar target:Object;\n\t\t\tvar altTarget:Object;\n\t\t\tfor each (var hitTester:ITouchHitTester in _hitTesters)\n\t\t\t{\n\t\t\t\ttarget = hitTester.hitTest(location, possibleTarget);\n\t\t\t\tif (target)\n\t\t\t\t{\n\t\t\t\t\tif ((target is Stage))\n\t\t\t\t\t{\n\t\t\t\t\t\t// NB! Target is flash.display::Stage is a special case. If it is true, we want\n\t\t\t\t\t\t// to give a try to a lower-priority (Stage3D) hit-testers. \n\t\t\t\t\t\taltTarget = target;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// We found a target.\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!target && !altTarget)\n\t\t\t{\n\t\t\t\tthrow new Error(\"Not touch target found (hit test).\" +\n\t\t\t\t\"Something is wrong, at least flash.display::Stage should be found.\" +\n\t\t\t\t\"See Gestouch#addTouchHitTester() and Gestouch#inputAdapter.\");\n\t\t\t}\n\t\t\t\n\t\t\ttouch.target = target || altTarget;\n\t\t\ttouch.setLocation(x, y, getTimer());\n\t\t\t\n\t\t\t_touchesMap[touchID] = touch;\n\t\t\t_activeTouchesCount++;\n\t\t\t\n\t\t\t_gesturesManager.onTouchBegin(touch);\n\t\t\t\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchMove(touchID:uint, x:Number, y:Number):void\n\t\t{\n\t\t\tconst touch:Touch = _touchesMap[touchID] as Touch;\n\t\t\tif (!touch)\n\t\t\t\treturn;// touch with specified ID isn't registered\n\t\t\t\n\t\t\tif (touch.updateLocation(x, y, getTimer()))\n\t\t\t{\n\t\t\t\t// NB! It appeared that native TOUCH_MOVE event is dispatched also when\n\t\t\t\t// the location is the same, but size has changed. We are only interested\n\t\t\t\t// in location at the moment, so we shall ignore irrelevant calls.\n\t\t\t\t\n\t\t\t\t_gesturesManager.onTouchMove(touch);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchEnd(touchID:uint, x:Number, y:Number):void\n\t\t{\n\t\t\tconst touch:Touch = _touchesMap[touchID] as Touch;\n\t\t\tif (!touch)\n\t\t\t\treturn;// touch with specified ID isn't registered\n\t\t\t\n\t\t\ttouch.updateLocation(x, y, getTimer());\n\t\t\t\n\t\t\tdelete _touchesMap[touchID];\n\t\t\t_activeTouchesCount--;\n\t\t\t\n\t\t\t_gesturesManager.onTouchEnd(touch);\n\t\t\t\n\t\t\ttouch.target = null;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function onTouchCancel(touchID:uint, x:Number, y:Number):void\n\t\t{\n\t\t\tconst touch:Touch = _touchesMap[touchID] as Touch;\n\t\t\tif (!touch)\n\t\t\t\treturn;// touch with specified ID isn't registered\n\t\t\t\n\t\t\ttouch.updateLocation(x, y, getTimer());\n\t\t\t\n\t\t\tdelete _touchesMap[touchID];\n\t\t\t_activeTouchesCount--;\n\t\t\t\n\t\t\t_gesturesManager.onTouchCancel(touch);\n\t\t\t\n\t\t\ttouch.target = null;\n\t\t}\n\t\t\n\t\t\n\t\tprotected function createTouch():Touch\n\t\t{\n\t\t\t//TODO: pool\n\t\t\treturn new Touch();\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * Sorts from higher priority to lower. Items with the same priority keep the order\n\t\t * of addition, e.g.:\n\t\t * add(a), add(b), add(c, -1), add(d, 1) will be ordered to\n\t\t * d, a, b, c\n\t\t */\n\t\tprotected function hitTestersSorter(x:ITouchHitTester, y:ITouchHitTester):Number\n\t\t{\n\t\t\tconst d:int = int(_hitTesterPrioritiesMap[x]) - int(_hitTesterPrioritiesMap[y]);\n\t\t\tif (d > 0)\n\t\t\t\treturn -1;\n\t\t\telse if (d < 0)\n\t\t\t\treturn 1;\n\t\t\t\n\t\t\treturn _hitTesters.indexOf(x) > _hitTesters.indexOf(y) ? 1 : -1;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/core/gestouch_internal.as",
    "content": "package org.gestouch.core\n{\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic namespace gestouch_internal = \"org.gestouch.core::gestouch_internal\";\n}"
  },
  {
    "path": "src/org/gestouch/events/GestureEvent.as",
    "content": "package org.gestouch.events\n{\n\timport org.gestouch.core.GestureState;\n\n\timport flash.events.Event;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class GestureEvent extends Event\n\t{\n\t\tpublic static const GESTURE_POSSIBLE:String = \"gesturePossible\";\n\t\tpublic static const GESTURE_RECOGNIZED:String = \"gestureRecognized\";\n\t\tpublic static const GESTURE_BEGAN:String = \"gestureBegan\";\n\t\tpublic static const GESTURE_CHANGED:String = \"gestureChanged\";\n\t\tpublic static const GESTURE_ENDED:String = \"gestureEnded\";\n\t\tpublic static const GESTURE_CANCELLED:String = \"gestureCancelled\";\n\t\tpublic static const GESTURE_FAILED:String = \"gestureFailed\";\n\t\t\n\t\tpublic static const GESTURE_STATE_CHANGE:String = \"gestureStateChange\";\n\t\t\n\t\t\n\t\tpublic var newState:GestureState;\n\t\tpublic var oldState:GestureState;\n\t\t\n\t\t\n\t\tpublic function GestureEvent(type:String, newState:GestureState, oldState:GestureState)\n\t\t{\n\t\t\tsuper(type, false, false);\n\t\t\t\n\t\t\tthis.newState = newState;\n\t\t\tthis.oldState = oldState;\n\t\t}\n\t\t\n\t\t\n\t\toverride public function clone():Event\n\t\t{\n\t\t\treturn new GestureEvent(type, newState, oldState);\n\t\t}\n\t\t\n\t\t\n\t\toverride public function toString():String\n\t\t{\n\t\t\treturn formatToString(\"GestureEvent\", \"type\", \"oldState\", \"newState\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/extensions/native/DisplayObjectUtils.as",
    "content": "package org.gestouch.extensions.native\n{\nimport flash.display.DisplayObject;\nimport flash.display.DisplayObjectContainer;\nimport flash.display.InteractiveObject;\nimport flash.display.Stage;\nimport flash.geom.Point;\n\n\n/**\n * @author    Valentin Simonov\n */\npublic class DisplayObjectUtils\n{\n\t/**\n\t * Searches display list for top most instance of InteractiveObject.\n\t * Checks if mouseEnabled is true and (optionally) parent's mouseChildren.\n\t * @param stage                Stage object.\n\t * @param point                Global point to test.\n\t * @param mouseChildren        If true also checks parents chain for mouseChildren == true.\n\t * @param startFrom            An index to start looking from in objects under point array.\n\t * @return                    Top most InteractiveObject or Stage.\n\t */\n\tpublic static function getTopTarget(stage:Stage, point:Point, mouseChildren:Boolean = true, startFrom:uint = 0):InteractiveObject\n\t{\n\t\tvar targets:Array = stage.getObjectsUnderPoint(point);\n\t\tif (!targets.length) return stage;\n\n\t\tvar startIndex:int = targets.length - 1 - startFrom;\n\t\tif (startIndex < 0) return stage;\n\n\t\touter:\n\t\t\t\tfor (var i:int = startIndex; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tvar target:DisplayObject = targets[i] as DisplayObject;\n\t\t\t\t\twhile (target != stage)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (target is InteractiveObject)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ((target as InteractiveObject).mouseEnabled)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (mouseChildren)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar lastMouseActive:InteractiveObject = target as InteractiveObject;\n\t\t\t\t\t\t\t\t\tvar parent:DisplayObjectContainer = target.parent;\n\t\t\t\t\t\t\t\t\twhile (parent)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif (!lastMouseActive && parent.mouseEnabled)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlastMouseActive = parent;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if (!parent.mouseChildren)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif (parent.mouseEnabled)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlastMouseActive = parent;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlastMouseActive = null;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tparent = parent.parent;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (lastMouseActive)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\treturn lastMouseActive;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\treturn stage;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn target as InteractiveObject;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontinue outer;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttarget = target.parent;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\treturn stage;\n\t}\n}\n}\n"
  },
  {
    "path": "src/org/gestouch/extensions/native/NativeDisplayListAdapter.as",
    "content": "package org.gestouch.extensions.native\n{\n\timport flash.display.DisplayObject;\n\timport flash.display.DisplayObjectContainer;\n\timport flash.display.Stage;\n\timport flash.geom.Point;\n\timport flash.utils.Dictionary;\n\timport org.gestouch.core.IDisplayListAdapter;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tfinal public class NativeDisplayListAdapter implements IDisplayListAdapter\n\t{\n\t\tprivate var _targetWeekStorage:Dictionary;\n\t\t\n\t\t\n\t\tpublic function NativeDisplayListAdapter(target:DisplayObject = null)\n\t\t{\n\t\t\tif (target)\n\t\t\t{\n\t\t\t\t_targetWeekStorage = new Dictionary(true);\n\t\t\t\t_targetWeekStorage[target] = true;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tpublic function get target():Object\n\t\t{\n\t\t\tfor (var key:Object in _targetWeekStorage)\n\t\t\t{\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function contains(object:Object):Boolean\n\t\t{\n\t\t\tconst targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer;\n\t\t\tif (targetAsDOC is Stage)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst objectAsDO:DisplayObject = object as DisplayObject;\n\t\t\tif (objectAsDO)\n\t\t\t{\n\t\t\t\treturn (targetAsDOC && targetAsDOC.contains(objectAsDO));\n\t\t\t}\n\t\t\t/**\n\t\t\t * There might be case when we use some old \"software\" 3D library for instace,\n\t\t\t * which viewport is added to classic Display List. So native stage, root and some other\n\t\t\t * sprites will actually be parents of 3D objects. To ensure all gestures (both for\n\t\t\t * native and 3D objects) work correctly with each other contains() method should be\n\t\t\t * a bit more sophisticated.\n\t\t\t * But as all 3D engines (at least it looks like that) are moving towards Stage3D layer\n\t\t\t * this task doesn't seem significant anymore. So I leave this implementation as\n\t\t\t * comments in case someone will actually need it.\n\t\t\t * Just uncomment this and it should work. \n\t\t\t\n\t\t\t// else: more complex case.\n\t\t\t// object is not of the same type as this.target (flash.display::DisplayObject)\n\t\t\t// it might we some 3D library object in it's viewport (which itself is in DisplayList).\n\t\t\t// So we perform more general check:\n\t\t\tconst adapter:IDisplayListAdapter = Gestouch.gestouch_internal::getDisplayListAdapter(object);\n\t\t\tif (adapter)\n\t\t\t{\n\t\t\t\treturn adapter.getHierarchy(object).indexOf(this.target) > -1;\n\t\t\t}\n\t\t\t*/\n\t\t\t\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function getHierarchy(genericTarget:Object):Vector.<Object>\n\t\t{\n\t\t\tvar list:Vector.<Object> = new Vector.<Object>();\n\t\t\tvar i:uint = 0;\n\t\t\tvar target:DisplayObject = genericTarget as DisplayObject;\n\t\t\twhile (target)\n\t\t\t{\n\t\t\t\tlist[i] = target;\n\t\t\t\ttarget = target.parent;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\t\n\t\t\treturn list;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function reflect():Class\n\t\t{\n\t\t\treturn NativeDisplayListAdapter;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/extensions/native/NativeTouchHitTester.as",
    "content": "package org.gestouch.extensions.native\n{\n\timport flash.display.DisplayObject;\n\timport flash.display.Stage;\n\timport flash.geom.Point;\n\n\timport org.gestouch.core.ITouchHitTester;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class NativeTouchHitTester implements ITouchHitTester\n\t{\n\t\tprivate var stage:Stage;\n\n\n\t\tpublic function NativeTouchHitTester(stage:Stage)\n\t\t{\n\t\t\tif (!stage)\n\t\t\t{\n\t\t\t\tthrow ArgumentError(\"Missing stage argument.\");\n\t\t\t}\n\n\t\t\tthis.stage = stage;\n\t\t}\n\n\n\t\tpublic function hitTest(point:Point, possibleTarget:Object = null):Object\n\t\t{\n\t\t\tif (possibleTarget && possibleTarget is DisplayObject)\n\t\t\t{\n\t\t\t\treturn possibleTarget;\n\t\t\t}\n\n\t\t\t// Fallback target detection through getObjectsUnderPoint\n\t\t\treturn DisplayObjectUtils.getTopTarget(stage, point);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/extensions/starling/StarlingDisplayListAdapter.as",
    "content": "package org.gestouch.extensions.starling\n{\n\timport starling.display.DisplayObject;\n\timport starling.display.DisplayObjectContainer;\n\n\timport org.gestouch.core.IDisplayListAdapter;\n\n\timport flash.utils.Dictionary;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tfinal public class StarlingDisplayListAdapter implements IDisplayListAdapter\n\t{\n\t\tprivate var targetWeekStorage:Dictionary;\n\t\t\n\t\t\n\t\tpublic function StarlingDisplayListAdapter(target:DisplayObject = null)\n\t\t{\n\t\t\tif (target)\n\t\t\t{\n\t\t\t\ttargetWeekStorage = new Dictionary(true);\n\t\t\t\ttargetWeekStorage[target] = true;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tpublic function get target():Object\n\t\t{\n\t\t\tfor (var key:Object in targetWeekStorage)\n\t\t\t{\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function contains(object:Object):Boolean\n\t\t{\n\t\t\tconst targetAsDOC:DisplayObjectContainer = this.target as DisplayObjectContainer;\n\t\t\tconst objectAsDO:DisplayObject = object as DisplayObject;\n\t\t\treturn (targetAsDOC && objectAsDO && targetAsDOC.contains(objectAsDO));\n\t\t}\n\t\t\n\t\t\n\t\tpublic function getHierarchy(genericTarget:Object):Vector.<Object>\n\t\t{\n\t\t\tvar list:Vector.<Object> = new Vector.<Object>();\n\t\t\tvar i:uint = 0;\n\t\t\tvar target:DisplayObject = genericTarget as DisplayObject;\n\t\t\twhile (target)\n\t\t\t{\n\t\t\t\tlist[i] = target;\n\t\t\t\ttarget = target.parent;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\t\n\t\t\treturn list;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function reflect():Class\n\t\t{\n\t\t\treturn StarlingDisplayListAdapter;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/extensions/starling/StarlingTouchHitTester.as",
    "content": "package org.gestouch.extensions.starling\n{\n\timport flash.geom.Point;\n\n\timport org.gestouch.core.ITouchHitTester;\n\n\timport starling.core.Starling;\n\timport starling.display.DisplayObject;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class StarlingTouchHitTester implements ITouchHitTester\n\t{\n\t\tprivate var starling:Starling;\n\n\n\t\tpublic function StarlingTouchHitTester(starling:Starling)\n\t\t{\n\t\t\tif (!starling)\n\t\t\t{\n\t\t\t\tthrow ArgumentError(\"Missing starling argument.\");\n\t\t\t}\n\n\t\t\tthis.starling = starling;\n\t\t}\n\n\n\t\tpublic function hitTest(point:Point, possibleTarget:Object = null):Object\n\t\t{\n\t\t\tif (possibleTarget && possibleTarget is DisplayObject)\n\t\t\t{\n\t\t\t\treturn possibleTarget;\n\t\t\t}\n\n\t\t\tpoint = StarlingUtils.adjustGlobalPoint(starling, point);\n\t\t\treturn starling.stage.hitTest(point, true);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/extensions/starling/StarlingUtils.as",
    "content": "package org.gestouch.extensions.starling\n{\n\timport starling.display.Stage;\n\timport starling.core.Starling;\n\n\timport flash.geom.Point;\n\timport flash.geom.Rectangle;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tfinal public class StarlingUtils\n\t{\n\t\t/**\n\t\t * Transforms real global point (in the scope of flash.display::Stage) into\n\t\t * starling stage \"global\" coordinates.\n\t\t */\n\t\tpublic static function adjustGlobalPoint(starling:Starling, point:Point):Point\n\t\t{\n\t\t\tconst vp:Rectangle = starling.viewPort;\n\t\t\tconst stStage:Stage = starling.stage;\n\t\t\t\n\t\t\tif (vp.x != 0 || vp.y != 0 ||\n\t\t\t\tstStage.stageWidth != vp.width || stStage.stageHeight != vp.height)\n\t\t\t{\n\t\t\t\tpoint = point.clone();\n\t\t\t\t\n\t\t\t\t// Same transformation they do in Starling\n\t\t\t\t// WTF!? https://github.com/PrimaryFeather/Starling-Framework/issues/72\n\t\t\t\tpoint.x = stStage.stageWidth * (point.x - vp.x) / vp.width;\n\t\t\t\tpoint.y = stStage.stageHeight * (point.y - vp.y) / vp.height;\n\t\t\t}\n\t\t\t\n\t\t\treturn point;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/gestures/AbstractContinuousGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.gestures.Gesture;\n\n\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.BEGAN.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureBegan\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.CHANGED.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureChanged\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.ENDED.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureEnded\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.CANCELLED.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureCancelled\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class AbstractContinuousGesture extends Gesture\n\t{\n\t\tpublic function AbstractContinuousGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/gestures/AbstractDiscreteGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.gestures.Gesture;\n\n\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.RECOGNIZED.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureRecognized\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class AbstractDiscreteGesture extends Gesture\n\t{\n\t\tpublic function AbstractDiscreteGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/gestures/Gesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.Gestouch;\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.GesturesManager;\n\timport org.gestouch.core.IGestureTargetAdapter;\n\timport org.gestouch.core.Touch;\n\timport org.gestouch.core.gestouch_internal;\n\timport org.gestouch.events.GestureEvent;\n\n\timport flash.errors.IllegalOperationError;\n\timport flash.events.EventDispatcher;\n\timport flash.geom.Point;\n\timport flash.system.Capabilities;\n\timport flash.utils.Dictionary;\n\t\n\tuse namespace gestouch_internal;\n\t\n\t\n\t/**\n\t * Dispatched when the state of the gesture changes.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureStateChange\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.POSSIBLE.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gesturePossible\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * Dispatched when the state of the gesture changes to GestureState.FAILED.\n\t * \n\t * @eventType org.gestouch.events.GestureEvent\n\t * @see #state\n\t */\n\t[Event(name=\"gestureFailed\", type=\"org.gestouch.events.GestureEvent\")]\n\t/**\n\t * Base class for all gestures. Gesture is essentially a detector that tracks touch points\n\t * in order detect specific gesture motion and form gesture event on target.\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class Gesture extends EventDispatcher\n\t{\n\t\t/**\n\t\t * Threshold for screen distance they must move to count as valid input \n\t\t * (not an accidental offset on touch), \n\t\t * based on 20 pixels on a 252ppi device.\n\t\t */\n\t\tpublic static var DEFAULT_SLOP:uint = Math.round(20 / 252 * flash.system.Capabilities.screenDPI);\n\t\t\n\t\t/**\n\t\t * If a gesture should receive a touch.\n\t\t * Callback signature: function(gesture:Gesture, touch:Touch):Boolean\n\t\t * \n\t\t * @see Touch\n\t\t */\n\t\tpublic var gestureShouldReceiveTouchCallback:Function;\n\t\t/**\n\t\t * If a gesture should be recognized (transition from state POSSIBLE to state RECOGNIZED or BEGAN).\n\t\t * Returning <code>false</code> causes the gesture to transition to the FAILED state.\n\t\t * \n\t\t * Callback signature: function(gesture:Gesture):Boolean\n\t\t * \n\t\t * @see state\n\t\t * @see GestureState\n\t\t */\n\t\tpublic var gestureShouldBeginCallback:Function;\n\t\t/**\n\t\t * If two gestures should be allowed to recognize simultaneously.\n\t\t * \n\t\t * Callback signature: function(gesture:Gesture, otherGesture:Gesture):Boolean\n\t\t */\n\t\tpublic var gesturesShouldRecognizeSimultaneouslyCallback:Function;\n\t\t\n\t\t\n\t\tprotected const _gesturesManager:GesturesManager = Gestouch.gesturesManager;\n\t\t/**\n\t\t * Map (generic object) of tracking touch points, where keys are touch points IDs.\n\t\t */\n\t\tprotected var _touchesMap:Object = {};\n\t\tprotected var _centralPoint:Point = new Point();\n\t\t/**\n\t\t * List of gesture we require to fail.\n\t\t * @see requireGestureToFail()\n\t\t */\n\t\tprotected var _gesturesToFail:Dictionary = new Dictionary(true);\n\t\tprotected var _pendingRecognizedState:GestureState;\n\t\t\n\t\t\n\t\tpublic function Gesture(target:Object = null)\n\t\t{\n\t\t\tsuper();\n\t\t\t\n\t\t\tpreinit();\n\t\t\t\n\t\t\tthis.target = target;\n\t\t}\n\t\t\n\t\t\n\t\t/** @private */\n\t\tprotected var _targetAdapter:IGestureTargetAdapter;\n\t\t/**\n\t\t * \n\t\t */\n\t\tgestouch_internal function get targetAdapter():IGestureTargetAdapter\n\t\t{\n\t\t\treturn _targetAdapter;\n\t\t}\n\t\tprotected function get targetAdapter():IGestureTargetAdapter\n\t\t{\n\t\t\treturn _targetAdapter;\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * FIXME\n\t\t * InteractiveObject (DisplayObject) which this gesture is tracking the actual gesture motion on.\n\t\t * \n\t\t * <p>Could be some image, component (like map) or the larger view like Stage.</p>\n\t\t * \n\t\t * <p>You can change the target in the runtime, e.g. you have a gallery\n\t\t * where only one item is visible at the moment, so use one gesture instance\n\t\t * and change the target to the currently visible item.</p>\n\t\t * \n\t\t * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/InteractiveObject.html\n\t\t */\n\t\tpublic function get target():Object\n\t\t{\n\t\t\treturn _targetAdapter ? _targetAdapter.target : null;\n\t\t}\n\t\tpublic function set target(value:Object):void\n\t\t{\n\t\t\tvar target:Object = this.target;\n\t\t\tif (target == value)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tuninstallTarget(target);\n\t\t\t_targetAdapter = value ? Gestouch.createGestureTargetAdapter(value) : null;\n\t\t\tinstallTarget(value);\n\t\t}\n\t\t\n\t\t\n\t\t/** @private */\n\t\tprotected var _enabled:Boolean = true;\n\t\t\n\t\t/** \n\t\t * @default true\n\t\t */\n\t\tpublic function get enabled():Boolean\n\t\t{\n\t\t\treturn _enabled;\n\t\t}\n\t\tpublic function set enabled(value:Boolean):void\n\t\t{\n\t\t\tif (_enabled == value)\n\t\t\t\treturn;\n\t\t\t\n\t\t\t_enabled = value;\n\t\t\t\n\t\t\tif (!_enabled)\n\t\t\t{\n\t\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.CANCELLED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _state:GestureState = GestureState.POSSIBLE;\n\t\tpublic function get state():GestureState\n\t\t{\n\t\t\treturn _state;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _idle:Boolean = true;\n\t\tgestouch_internal function get idle():Boolean\n\t\t{\n\t\t\treturn _idle;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _touchesCount:uint = 0;\n\t\t/**\n\t\t * Amount of currently tracked touch points.\n\t\t * \n\t\t * @see #_touches\n\t\t */\n\t\tpublic function get touchesCount():uint\n\t\t{\n\t\t\treturn _touchesCount;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _location:Point = new Point();\n\t\t/**\n\t\t * Virtual central touch point among all tracking touch points (geometrical center).\n\t\t */\n\t\tpublic function get location():Point\n\t\t{\n\t\t\treturn _location.clone();\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Public methods\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\t[Abstract]\n\t\t/**\n\t\t * Reflects gesture class (for better perfomance).\n\t\t * \n\t\t * <p><b>NB!</b> This is abstract method and must be overridden.</p>\n\t\t * \n\t\t * @see performance optimization tips\n\t\t */\n\t\tpublic function reflect():Class\n\t\t{\n\t\t\tthrow Error(\"reflect() is abstract method and must be overridden.\");\n\t\t}\n\t\t\n\t\t\n\t\tpublic function isTrackingTouch(touchID:uint):Boolean\n\t\t{\n\t\t\treturn (_touchesMap[touchID] != undefined);\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * Cancels current tracking (interaction) cycle.\n\t\t * \n\t\t * <p>Could be useful to \"stop\" gesture for the current interaction cycle.</p>\n\t\t */\n\t\tpublic function reset():void\n\t\t{\n\t\t\tif (idle)\n\t\t\t\treturn;// Do nothing as we are idle and there is nothing to reset\n\t\t\t\n\t\t\tconst state:GestureState = this.state;//caching getter\n\t\t\t\n\t\t\t_location.x = 0;\n\t\t\t_location.y = 0;\n\t\t\t_touchesMap = {};\n\t\t\t_touchesCount = 0;\n\t\t\t_idle = true;\n\t\t\t\n\t\t\tfor (var key:* in _gesturesToFail)\n\t\t\t{\n\t\t\t\tvar gestureToFail:Gesture = key as Gesture;\n\t\t\t\tgestureToFail.removeEventListener(GestureEvent.GESTURE_STATE_CHANGE, gestureToFail_stateChangeHandler);\n\t\t\t}\n\t\t\t_pendingRecognizedState = null;\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\t// manual reset() call. Set to FAILED to keep our State Machine clean and stable\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t\telse if (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t{\n\t\t\t\t// manual reset() call. Set to CANCELLED to keep our State Machine clean and stable\n\t\t\t\tsetState(GestureState.CANCELLED);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// reset from GesturesManager after reaching one of the 4 final states:\n\t\t\t\t// (state == GestureState.RECOGNIZED ||\n\t\t\t\t// state == GestureState.ENDED ||\n\t\t\t\t// state == GestureState.FAILED ||\n\t\t\t\t// state == GestureState.CANCELLED)\n\t\t\t\tsetState(GestureState.POSSIBLE);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * Remove gesture and prepare it for GC.\n\t\t * \n\t\t * <p>The gesture is not able to use after calling this method.</p>\n\t\t */\n\t\tpublic function dispose():void\n\t\t{\n\t\t\t//TODO\n\t\t\treset();\n\t\t\ttarget = null;\n\t\t\tgestureShouldReceiveTouchCallback = null;\n\t\t\tgestureShouldBeginCallback = null;\n\t\t\tgesturesShouldRecognizeSimultaneouslyCallback = null;\n\t\t\t_gesturesToFail = null;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function canBePreventedByGesture(preventingGesture:Gesture):Boolean\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function canPreventGesture(preventedGesture:Gesture):Boolean\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * <b>NB! Current implementation is highly experimental!</b> See examples for more info. \n\t\t */\n\t\tpublic function requireGestureToFail(gesture:Gesture):void\n\t\t{\n\t\t\t//TODO\n\t\t\tif (!gesture)\n\t\t\t{\n\t\t\t\tthrow new ArgumentError();\n\t\t\t}\n\t\t\t\n\t\t\t_gesturesToFail[gesture] = true;\n\t\t}\n\t\t\n\t\t\n\n\n\t\t// --------------------------------------------------------------------------\n\t\t// \n\t\t// Protected methods\n\t\t// \n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\t/**\n\t\t * First method, called in constructor.\n\t\t */\n\t\tprotected function preinit():void\n\t\t{\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * Called internally when changing the target.\n\t\t * \n\t\t * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/InteractiveObject.html\n\t\t */\n\t\tprotected function installTarget(target:Object):void\n\t\t{\n\t\t\tif (target)\n\t\t\t{\n\t\t\t\t_gesturesManager.addGesture(this);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * Called internally when changing the target.\n\t\t * \n\t\t * <p>You should remove all listeners from target here.</p>\n\t\t * \n\t\t * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/InteractiveObject.html\n\t\t */\n\t\tprotected function uninstallTarget(target:Object):void\n\t\t{\n\t\t\tif (target)\n\t\t\t{\n\t\t\t\t_gesturesManager.removeGesture(this);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * TODO: clarify usage. For now it's supported to call this method in onTouchBegin with return.\n\t\t */\n\t\tprotected function ignoreTouch(touch:Touch):void\n\t\t{\n\t\t\tif (touch.id in _touchesMap)\n\t\t\t{\n\t\t\t\tdelete _touchesMap[touch.id];\n\t\t\t\t_touchesCount--;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprotected function failOrIgnoreTouch(touch:Touch):void\n\t\t{\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tignoreTouch(touch);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t[Abstract]\n\t\t/**\n\t\t * <p><b>NB!</b> This is abstract method and must be overridden.</p>\n\t\t */\n\t\tprotected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t}\n\t\t\n\t\t\n\t\t[Abstract]\n\t\t/**\n\t\t * <p><b>NB!</b> This is abstract method and must be overridden.</p>\n\t\t */\n\t\tprotected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t}\n\t\t\n\t\t\n\t\t[Abstract]\n\t\t/**\n\t\t * <p><b>NB!</b> This is abstract method and must be overridden.</p>\n\t\t */\n\t\tprotected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * \n\t\t */\n\t\tprotected function onTouchCancel(touch:Touch):void\n\t\t{\n\t\t}\n\t\t\n\t\t\n\t\tprotected function setState(newState:GestureState):Boolean\n\t\t{\n\t\t\tif (_state == newState && _state == GestureState.CHANGED)\n\t\t\t{\n\t\t\t\t// shortcut for better performance\n\t\t\t\t\n\t\t\t\tif (hasEventListener(GestureEvent.GESTURE_STATE_CHANGE))\n\t\t\t\t{\n\t\t\t\t\tdispatchEvent(new GestureEvent(GestureEvent.GESTURE_STATE_CHANGE, _state, _state));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (hasEventListener(GestureEvent.GESTURE_CHANGED))\n\t\t\t\t{\n\t\t\t\t\tdispatchEvent(new GestureEvent(GestureEvent.GESTURE_CHANGED, _state, _state));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tresetNotificationProperties();\n\t\t\t\t\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\tif (!_state.canTransitionTo(newState))\n\t\t\t{\n\t\t\t\tthrow new IllegalOperationError(\"You cannot change from state \" +\n\t\t\t\t\t_state + \" to state \" + newState  + \".\");\n\t\t\t}\n\t\t\t\n\t\t\tif (newState != GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\t// in case instantly switch state in touchBeganHandler()\n\t\t\t\t_idle = false;\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\tif (newState == GestureState.BEGAN || newState == GestureState.RECOGNIZED)\n\t\t\t{\n\t\t\t\tvar gestureToFail:Gesture;\n\t\t\t\tvar key:*;\n\t\t\t\t// first we check if other required-to-fail gestures recognized\n\t\t\t\t// TODO: is this really necessary? using \"requireGestureToFail\" API assume that\n\t\t\t\t// required-to-fail gesture always recognizes AFTER this one.\n\t\t\t\tfor (key in _gesturesToFail)\n\t\t\t\t{\n\t\t\t\t\tgestureToFail = key as Gesture;\n\t\t\t\t\tif (!gestureToFail.idle &&\n\t\t\t\t\t\tgestureToFail.state != GestureState.POSSIBLE &&\n\t\t\t\t\t\tgestureToFail.state != GestureState.FAILED)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Looks like other gesture won't fail,\n\t\t\t\t\t\t// which means the required condition will not happen, so we must fail\n\t\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// then we check if other required-to-fail gestures are actually tracked (not IDLE)\n\t\t\t\t// and not still not recognized (e.g. POSSIBLE state)\n\t\t\t\tfor (key in _gesturesToFail)\n\t\t\t\t{\n\t\t\t\t\tgestureToFail = key as Gesture;\n\t\t\t\t\tif (gestureToFail.state == GestureState.POSSIBLE)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Other gesture might fail soon, so we postpone state change\n\t\t\t\t\t\t_pendingRecognizedState = newState;\n\t\t\t\t\t\t\n\t\t\t\t\t\tfor (key in _gesturesToFail)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgestureToFail = key as Gesture;\n\t\t\t\t\t\t\tgestureToFail.addEventListener(GestureEvent.GESTURE_STATE_CHANGE, gestureToFail_stateChangeHandler, false, 0, true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t// else if gesture is in IDLE state it means it doesn't track anything,\n\t\t\t\t\t// so we simply ignore it as it doesn't seem like conflict from this perspective\n\t\t\t\t\t// (perspective of using \"requireGestureToFail\" API)\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif (gestureShouldBeginCallback != null && !gestureShouldBeginCallback(this))\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\t\n\t\t\tvar oldState:GestureState = _state;\t\n\t\t\t_state = newState;\n\t\t\t\n\t\t\tif (_state.isEndState)\n\t\t\t{\n\t\t\t\t_gesturesManager.scheduleGestureStateReset(this);\n\t\t\t}\n\t\t\t\n\t\t\t//TODO: what if RTE happens in event handlers?\n\t\t\t\n\t\t\tif (hasEventListener(GestureEvent.GESTURE_STATE_CHANGE))\n\t\t\t{\n\t\t\t\tdispatchEvent(new GestureEvent(GestureEvent.GESTURE_STATE_CHANGE, _state, oldState));\n\t\t\t}\n\t\t\t\n\t\t\tif (hasEventListener(_state.toEventType()))\n\t\t\t{\n\t\t\t\tdispatchEvent(new GestureEvent(_state.toEventType(), _state, oldState));\n\t\t\t}\n\t\t\t\n\t\t\tresetNotificationProperties();\n\t\t\t\n\t\t\tif (_state == GestureState.BEGAN || _state == GestureState.RECOGNIZED)\n\t\t\t{\n\t\t\t\t_gesturesManager.onGestureRecognized(this);\n\t\t\t}\n\t\t\t\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function setState_internal(state:GestureState):void\n\t\t{\n\t\t\tsetState(state);\n\t\t}\n\t\t\n\t\t\n\t\tprotected function updateCentralPoint():void\n\t\t{\n\t\t\tvar touchLocation:Point;\n\t\t\tvar x:Number = 0;\n\t\t\tvar y:Number = 0;\n\t\t\tfor (var touchID:String in _touchesMap)\n\t\t\t{\n\t\t\t\ttouchLocation = (_touchesMap[int(touchID)] as Touch).location; \n\t\t\t\tx += touchLocation.x;\n\t\t\t\ty += touchLocation.y;\n\t\t\t}\n\t\t\t_centralPoint.x = x / _touchesCount;\n\t\t\t_centralPoint.y = y / _touchesCount;\n\t\t}\n\t\t\n\t\t\n\t\tprotected function updateLocation():void\n\t\t{\n\t\t\tupdateCentralPoint();\n\t\t\t_location.x = _centralPoint.x;\n\t\t\t_location.y = _centralPoint.y;\n\t\t}\n\t\t\n\t\t\n\t\tprotected function resetNotificationProperties():void\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Event handlers\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tgestouch_internal function touchBeginHandler(touch:Touch):void\n\t\t{\n\t\t\t_touchesMap[touch.id] = touch;\n\t\t\t_touchesCount++;\n\t\t\t\n\t\t\tonTouchBegin(touch);\n\t\t\t\n\t\t\tif (_touchesCount == 1 && state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\t_idle = false;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function touchMoveHandler(touch:Touch):void\n\t\t{\n\t\t\t_touchesMap[touch.id] = touch;\n\t\t\tonTouchMove(touch);\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function touchEndHandler(touch:Touch):void\n\t\t{\n\t\t\tdelete _touchesMap[touch.id];\n\t\t\t_touchesCount--;\n\t\t\t\n\t\t\tonTouchEnd(touch);\n\t\t}\n\t\t\n\t\t\n\t\tgestouch_internal function touchCancelHandler(touch:Touch):void\n\t\t{\n\t\t\tdelete _touchesMap[touch.id];\n\t\t\t_touchesCount--;\n\t\t\t\n\t\t\tonTouchCancel(touch);\n\t\t\t\n\t\t\tif (!state.isEndState)\n\t\t\t{\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.CANCELLED);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprotected function gestureToFail_stateChangeHandler(event:GestureEvent):void\n\t\t{\n\t\t\tif (!_pendingRecognizedState || state != GestureState.POSSIBLE)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tif (event.newState == GestureState.FAILED)\n\t\t\t{\n\t\t\t\tfor (var key:* in _gesturesToFail)\n\t\t\t\t{\n\t\t\t\t\tvar gestureToFail:Gesture = key as Gesture;\n\t\t\t\t\tif (gestureToFail.state == GestureState.POSSIBLE)\n\t\t\t\t\t{\n\t\t\t\t\t\t// we're still waiting for some gesture to fail\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// at this point all gestures-to-fail are either in IDLE or in FAILED states\n\t\t\t\tsetState(_pendingRecognizedState);\n\t\t\t}\n\t\t\telse if (event.newState != GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\t//TODO: need to re-think this over\n\t\t\t\t\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/gestures/LongPressGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\n\timport flash.events.TimerEvent;\n\timport flash.utils.Timer;\n\n\n\t/**\n\t * TODO:\n\t * - add numTapsRequired\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class LongPressGesture extends AbstractContinuousGesture\n\t{\n\t\tpublic var numTouchesRequired:uint = 1;\n\t\t/**\n\t\t * The minimum time interval in millisecond fingers must press on the target for the gesture to be recognized.\n\t\t * \n\t\t * @default 500\n\t\t */\n\t\tpublic var minPressDuration:uint = 500;\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP;\n\t\t\n\t\tprotected var _timer:Timer;\n\t\tprotected var _numTouchesRequiredReached:Boolean;\n\t\t\n\t\t\n\t\tpublic function LongPressGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn LongPressGesture;\n\t\t}\n\t\t\n\t\t\n\t\toverride public function reset():void\n\t\t{\n\t\t\tsuper.reset();\n\t\t\t\n\t\t\t_numTouchesRequiredReached = false;\n\t\t\t_timer.reset();\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function preinit():void\n\t\t{\n\t\t\tsuper.preinit();\n\t\t\t\n\t\t\t_timer = new Timer(minPressDuration, 1);\n\t\t\t_timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > numTouchesRequired)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == numTouchesRequired)\n\t\t\t{\n\t\t\t\t_numTouchesRequiredReached = true;\n\t\t\t\t_timer.reset();\n\t\t\t\t_timer.delay = minPressDuration || 1;\n\t\t\t\t_timer.start();\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tif (state == GestureState.POSSIBLE && slop > 0 && touch.locationOffset.length > slop)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t\telse if (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t{\n\t\t\t\tupdateLocation();\n\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (_numTouchesRequiredReached)\n\t\t\t{\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tupdateLocation();\n\t\t\t\t\tsetState(GestureState.ENDED);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Event handlers\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function timer_timerCompleteHandler(event:TimerEvent = null):void\n\t\t{\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tupdateLocation();\n\t\t\t\tsetState(GestureState.BEGAN);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/PanGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\n\timport flash.geom.Point;\n\n\n\t/**\n\t * TODO:\n\t * -location\n\t * -check native behavior on iDevice\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class PanGesture extends AbstractContinuousGesture\n\t{\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP;\n\t\t/**\n\t\t * Used for initial slop overcome calculations only.\n\t\t */\n\t\tpublic var direction:uint = PanGestureDirection.NO_DIRECTION;\n\t\t\n\t\t\n\t\tpublic function PanGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\t/** @private */\n\t\tprivate var _maxNumTouchesRequired:uint = uint.MAX_VALUE;\n\t\t\n\t\t/**\n\t\t * \n\t\t */\n\t\tpublic function get maxNumTouchesRequired():uint\n\t\t{\n\t\t\treturn _maxNumTouchesRequired;\n\t\t}\n\t\tpublic function set maxNumTouchesRequired(value:uint):void\n\t\t{\n\t\t\tif (_maxNumTouchesRequired == value)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tif (value < minNumTouchesRequired)\n\t\t\t\tthrow ArgumentError(\"maxNumTouchesRequired must be not less then minNumTouchesRequired\");\n\t\t\t\n\t\t\t_maxNumTouchesRequired = value;\n\t\t}\n\t\t\n\t\t\n\t\t/** @private */\n\t\tprivate var _minNumTouchesRequired:uint = 1;\n\t\t\n\t\t/**\n\t\t * \n\t\t */\n\t\tpublic function get minNumTouchesRequired():uint\n\t\t{\n\t\t\treturn _minNumTouchesRequired;\n\t\t}\n\t\tpublic function set minNumTouchesRequired(value:uint):void\n\t\t{\n\t\t\tif (_minNumTouchesRequired == value)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tif (value > maxNumTouchesRequired)\n\t\t\t\tthrow ArgumentError(\"minNumTouchesRequired must be not greater then maxNumTouchesRequired\");\n\t\t\t\n\t\t\t_minNumTouchesRequired = value;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _offsetX:Number = 0;\n\t\tpublic function get offsetX():Number\n\t\t{\n\t\t\treturn _offsetX;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _offsetY:Number = 0;\n\t\tpublic function get offsetY():Number\n\t\t{\n\t\t\treturn _offsetY;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn PanGesture;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > maxNumTouchesRequired)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount >= minNumTouchesRequired)\n\t\t\t{\n\t\t\t\tupdateLocation();\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount < minNumTouchesRequired)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tvar prevLocationX:Number;\n\t\t\tvar prevLocationY:Number;\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tprevLocationX = _location.x;\n\t\t\t\tprevLocationY = _location.y;\n\t\t\t\tupdateLocation();\n\t\t\t\t\n\t\t\t\t// Check if finger moved enough for gesture to be recognized\n\t\t\t\tvar locationOffset:Point = touch.locationOffset;\n\t\t\t\tif (direction == PanGestureDirection.VERTICAL)\n\t\t\t\t{\n\t\t\t\t\tlocationOffset.x = 0;\n\t\t\t\t}\n\t\t\t\telse if (direction == PanGestureDirection.HORIZONTAL)\n\t\t\t\t{\n\t\t\t\t\tlocationOffset.y = 0;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (locationOffset.length > slop || slop != slop)//faster isNaN(slop)\n\t\t\t\t{\n\t\t\t\t\t// NB! += instead of = for the case when this gesture recognition is delayed via requireGestureToFail\n\t\t\t\t\t_offsetX += _location.x - prevLocationX;\n\t\t\t\t\t_offsetY += _location.y - prevLocationY;\n\t\t\t\t\t\n\t\t\t\t\tsetState(GestureState.BEGAN);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t{\n\t\t\t\tprevLocationX = _location.x;\n\t\t\t\tprevLocationY = _location.y;\n\t\t\t\tupdateLocation();\n\t\t\t\t_offsetX = _location.x - prevLocationX;\n\t\t\t\t_offsetY = _location.y - prevLocationY;\n\t\t\t\t\n\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount < minNumTouchesRequired)\n\t\t\t{\n\t\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.ENDED);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tupdateLocation();\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function resetNotificationProperties():void\n\t\t{\n\t\t\tsuper.resetNotificationProperties();\n\t\t\t\n\t\t\t_offsetX = _offsetY = 0;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/PanGestureDirection.as",
    "content": "package org.gestouch.gestures\n{\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class PanGestureDirection\n\t{\n\t\tpublic static const NO_DIRECTION:uint = 0;\n\t\tpublic static const VERTICAL:uint = 1 << 0;\n\t\tpublic static const HORIZONTAL:uint = 1 << 1;\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/RotateGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\n\timport flash.geom.Point;\n\n\n\t/**\n\t * TODO:\n\t * -check native behavior on iDevice\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class RotateGesture extends AbstractContinuousGesture\n\t{\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP;\n\t\t\n\t\tprotected var _touch1:Touch;\n\t\tprotected var _touch2:Touch;\n\t\tprotected var _transformVector:Point;\n\t\tprotected var _thresholdAngle:Number;\n\t\t\n\t\t\n\t\tpublic function RotateGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _rotation:Number = 0;\n\t\tpublic function get rotation():Number\n\t\t{\n\t\t\treturn _rotation;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn RotateGesture;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > 2)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == 1)\n\t\t\t{\n\t\t\t\t_touch1 = touch;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_touch2 = touch;\n\t\t\t\t\n\t\t\t\t_transformVector = _touch2.location.subtract(_touch1.location);\n\t\t\t\t\n\t\t\t\t// @see chord length formula\n\t\t\t\t_thresholdAngle = Math.asin(slop / (2 * _transformVector.length)) * 2;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount < 2)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tvar currTransformVector:Point = _touch2.location.subtract(_touch1.location);\n\t\t\tvar cross:Number = (_transformVector.x * currTransformVector.y) - (currTransformVector.x * _transformVector.y);\n\t\t\tvar dot:Number = (_transformVector.x * currTransformVector.x) + (_transformVector.y * currTransformVector.y);\n\t\t\tvar rotation:Number = Math.atan2(cross, dot);\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tconst absRotation:Number = rotation >= 0 ? rotation : -rotation;\n\t\t\t\tif (absRotation < _thresholdAngle)\n\t\t\t\t{\n\t\t\t\t\t// not recognized yet\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// adjust angle to avoid initial \"jump\"\n\t\t\t\trotation = rotation > 0 ? rotation - _thresholdAngle : rotation + _thresholdAngle;\n\t\t\t}\n\t\t\t\n\t\t\t_transformVector.x = currTransformVector.x;\n\t\t\t_transformVector.y = currTransformVector.y;\n\t\t\t_rotation = rotation;\n\t\t\t\n\t\t\tupdateLocation();\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tsetState(GestureState.BEGAN);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount == 0)\n\t\t\t{\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.ENDED);\n\t\t\t\t}\n\t\t\t\telse if (state == GestureState.POSSIBLE)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse// == 1\n\t\t\t{\n\t\t\t\tif (touch == _touch1)\n\t\t\t\t{\n\t\t\t\t\t_touch1 = _touch2;\n\t\t\t\t}\n\t\t\t\t_touch2 = null;\n\t\t\t\t\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tupdateLocation();\n\t\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function resetNotificationProperties():void\n\t\t{\n\t\t\tsuper.resetNotificationProperties();\n\t\t\t\n\t\t\t_rotation = 0;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/SwipeGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\timport org.gestouch.utils.GestureUtils;\n\n\timport flash.events.TimerEvent;\n\timport flash.geom.Point;\n\timport flash.system.Capabilities;\n\timport flash.utils.Timer;\n\n\n\t/**\n\t * Recognition logic:<br/>\n\t * 1. should be recognized during <code>maxDuration</code> period<br/>\n\t * 2. velocity >= minVelocity <b>OR</b> offset >= minOffset\n\t * \n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class SwipeGesture extends AbstractDiscreteGesture\n\t{\n\t\tprivate static const ANGLE:Number = 40 * GestureUtils.DEGREES_TO_RADIANS;\n\t\tprivate static const MAX_DURATION:uint = 500;\n\t\tprivate static const MIN_OFFSET:Number = Capabilities.screenDPI / 6;\n\t\tprivate static const MIN_VELOCITY:Number = 2 * MIN_OFFSET / MAX_DURATION;\n\t\t\n\t\t/**\n\t\t * \"Dirty\" region around touch begin location which is not taken into account for\n\t\t * recognition/failing algorithms.\n\t\t * \n\t\t * @default Gesture.DEFAULT_SLOP\n\t\t */\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP;\n\t\tpublic var numTouchesRequired:uint = 1;\n\t\tpublic var direction:uint = SwipeGestureDirection.ORTHOGONAL;\n\t\t\n\t\t/**\n\t\t * The duration of period (in milliseconds) in which SwipeGesture must be recognized.\n\t\t * If gesture is not recognized during this period it fails. Default value is 500 (half a\n\t\t * second) and generally should not be changed. You can change it though for some special\n\t\t * cases, most likely together with <code>minVelocity</code> and <code>minOffset</code>\n\t\t * to achieve really custom behavior. \n\t\t * \n\t\t * @default 500\n\t\t * \n\t\t * @see #minVelocity\n\t\t * @see #minOffset\n\t\t */\n\t\tpublic var maxDuration:uint = MAX_DURATION;\n\t\t\n\t\t/**\n\t\t * Minimum offset (in pixels) for gesture to be recognized.\n\t\t * Default value is <code>Capabilities.screenDPI / 6</code> and generally should not\n\t\t * be changed.\n\t\t */\n\t\tpublic var minOffset:Number = MIN_OFFSET;\n\t\t\n\t\t/**\n\t\t * Minimum velocity (in pixels per millisecond) for gesture to be recognized.\n\t\t * Default value is <code>2 * minOffset / maxDuration</code> and generally should not\n\t\t * be changed.\n\t\t * \n\t\t * @see #minOffset\n\t\t * @see #minDuration\n\t\t */\n\t\tpublic var minVelocity:Number = MIN_VELOCITY;\n\t\t\n\t\tprotected var _offset:Point = new Point();\n\t\tprotected var _startTime:int;\n\t\tprotected var _noDirection:Boolean;\n\t\tprotected var _avrgVel:Point = new Point();\n\t\tprotected var _timer:Timer;\n\t\t\n\t\t\n\t\tpublic function SwipeGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\tpublic function get offsetX():Number\n\t\t{\n\t\t\treturn _offset.x;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function get offsetY():Number\n\t\t{\n\t\t\treturn _offset.y;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn SwipeGesture;\n\t\t}\n\t\t\n\t\t\n\t\toverride public function reset():void\n\t\t{\n\t\t\t_startTime = 0;\n\t\t\t_offset.x = 0;\n\t\t\t_offset.y = 0;\n\t\t\t_timer.reset();\n\t\t\t\n\t\t\tsuper.reset();\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function preinit():void\n\t\t{\n\t\t\tsuper.preinit();\n\t\t\t\n\t\t\t_timer = new Timer(maxDuration, 1);\n\t\t\t_timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > numTouchesRequired)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == 1)\n\t\t\t{\n\t\t\t\t// Because we want to fail as quick as possible\n\t\t\t\t_startTime = touch.time;\n\t\t\t\t\n\t\t\t\t_timer.reset();\n\t\t\t\t_timer.delay = maxDuration;\n\t\t\t\t_timer.start();\n\t\t\t}\n\t\t\tif (touchesCount == numTouchesRequired)\n\t\t\t{\n\t\t\t\tupdateLocation();\n\t\t\t\t_avrgVel.x = _avrgVel.y = 0;\n\t\t\t\t\n\t\t\t\t// cache direction condition for performance\n\t\t\t\t_noDirection = (SwipeGestureDirection.ORTHOGONAL & direction) == 0;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount < numTouchesRequired)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tvar totalTime:int = touch.time - _startTime;\n\t\t\tif (totalTime == 0)\n\t\t\t\treturn;//It was somehow THAT MUCH performant on one Android tablet\n\t\t\t\n\t\t\tvar prevCentralPointX:Number = _centralPoint.x;\n\t\t\tvar prevCentralPointY:Number = _centralPoint.y;\n\t\t\tupdateCentralPoint();\n\t\t\t\n\t\t\t_offset.x = _centralPoint.x - _location.x;\n\t\t\t_offset.y = _centralPoint.y - _location.y;\n\t\t\tvar offsetLength:Number = _offset.length;\n\t\t\t\n\t\t\t// average velocity (total offset to total duration)\n\t\t\t_avrgVel.x = _offset.x / totalTime;\n\t\t\t_avrgVel.y = _offset.y / totalTime;\n\t\t\tvar avrgVel:Number = _avrgVel.length;\n\t\t\t\n\t\t\tif (_noDirection)\n\t\t\t{\n\t\t\t\tif ((offsetLength > slop || slop != slop) &&\n\t\t\t\t\t(avrgVel >= minVelocity || offsetLength >= minOffset))\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.RECOGNIZED);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar recentOffsetX:Number = _centralPoint.x - prevCentralPointX;\n\t\t\t\tvar recentOffsetY:Number = _centralPoint.y - prevCentralPointY;\n\t\t\t\t//faster Math.abs()\n\t\t\t\tvar absVelX:Number = _avrgVel.x > 0 ? _avrgVel.x : -_avrgVel.x;\n\t\t\t\tvar absVelY:Number = _avrgVel.y > 0 ? _avrgVel.y : -_avrgVel.y;\n\t\t\t\t\n\t\t\t\tif (absVelX > absVelY)\n\t\t\t\t{\n\t\t\t\t\tvar absOffsetX:Number = _offset.x > 0 ? _offset.x : -_offset.x;\n\t\t\t\t\t\n\t\t\t\t\tif (absOffsetX > slop || slop != slop)//faster isNaN()\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((recentOffsetX < 0 && (direction & SwipeGestureDirection.LEFT) == 0) ||\n\t\t\t\t\t\t\t(recentOffsetX > 0 && (direction & SwipeGestureDirection.RIGHT) == 0) ||\n\t\t\t\t\t\t\tMath.abs(Math.atan(_offset.y/_offset.x)) > ANGLE)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// movement in opposite direction\n\t\t\t\t\t\t\t// or too much diagonally\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (absVelX >= minVelocity || absOffsetX >= minOffset)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_offset.y = 0;\n\t\t\t\t\t\t\tsetState(GestureState.RECOGNIZED);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (absVelY > absVelX)\n\t\t\t\t{\n\t\t\t\t\tvar absOffsetY:Number = _offset.y > 0 ? _offset.y : -_offset.y;\n\t\t\t\t\tif (absOffsetY > slop || slop != slop)//faster isNaN()\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((recentOffsetY < 0 && (direction & SwipeGestureDirection.UP) == 0) ||\n\t\t\t\t\t\t\t(recentOffsetY > 0 && (direction & SwipeGestureDirection.DOWN) == 0) ||\n\t\t\t\t\t\t\tMath.abs(Math.atan(_offset.x/_offset.y)) > ANGLE)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// movement in opposite direction\n\t\t\t\t\t\t\t// or too much diagonally\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (absVelY >= minVelocity || absOffsetY >= minOffset)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_offset.x = 0;\n\t\t\t\t\t\t\tsetState(GestureState.RECOGNIZED);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Give some tolerance for accidental offset on finger press (slop)\n\t\t\t\telse if (offsetLength > slop || slop != slop)//faster isNaN()\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount < numTouchesRequired)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function resetNotificationProperties():void\n\t\t{\n\t\t\tsuper.resetNotificationProperties();\n\t\t\t\n\t\t\t_offset.x = _offset.y = 0;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Event handlers\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function timer_timerCompleteHandler(event:TimerEvent):void\n\t\t{\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/SwipeGestureDirection.as",
    "content": "package org.gestouch.gestures\n{\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class SwipeGestureDirection\n\t{\n\t\tpublic static const RIGHT:uint = 1 << 0;\n\t\tpublic static const LEFT:uint = 1 << 1;\n\t\tpublic static const UP:uint = 1 << 2;\n\t\tpublic static const DOWN:uint = 1 << 3;\n\t\t\n\t\tpublic static const NO_DIRECTION:uint = 0;\n\t\tpublic static const HORIZONTAL:uint = RIGHT | LEFT;\n\t\tpublic static const VERTICAL:uint = UP | DOWN;\n\t\tpublic static const ORTHOGONAL:uint = RIGHT | LEFT | UP | DOWN;\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/TapGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport flash.geom.Point;\n\timport org.gestouch.core.gestouch_internal;\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\n\timport flash.events.TimerEvent;\n\timport flash.utils.Timer;\n\t\n\tuse namespace gestouch_internal;\n\n\n\t/**\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class TapGesture extends AbstractDiscreteGesture\n\t{\n\t\tpublic var numTouchesRequired:uint = 1;\n\t\tpublic var numTapsRequired:uint = 1;\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP << 2;//iOS has 45px for 132 dpi screen\n\t\tpublic var maxTapDelay:uint = 400;\n\t\tpublic var maxTapDuration:uint = 1500;\n\t\tpublic var maxTapDistance:Number = Gesture.DEFAULT_SLOP << 2;\n\t\t\n\t\tprotected var _timer:Timer;\n\t\tprotected var _numTouchesRequiredReached:Boolean;\n\t\tprotected var _tapCounter:uint = 0;\n\t\tprotected var _touchBeginLocations:Vector.<Point> = new Vector.<Point>();\n\t\t\n\t\t\n\t\tpublic function TapGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn TapGesture;\n\t\t}\n\t\t\n\t\t\n\t\toverride public function reset():void\n\t\t{\n\t\t\t_numTouchesRequiredReached = false;\n\t\t\t_tapCounter = 0;\n\t\t\t_timer.reset();\n\t\t\t_touchBeginLocations.length = 0;\n\t\t\t\n\t\t\tsuper.reset();\n\t\t}\n\t\t\n\t\t\n\t\toverride gestouch_internal function canPreventGesture(preventedGesture:Gesture):Boolean\n\t\t{\n\t\t\tif (preventedGesture is TapGesture &&\n\t\t\t\t(preventedGesture as TapGesture).numTapsRequired > this.numTapsRequired)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function preinit():void\n\t\t{\n\t\t\tsuper.preinit();\n\t\t\t\n\t\t\t_timer = new Timer(maxTapDelay, 1);\n\t\t\t_timer.addEventListener(TimerEvent.TIMER_COMPLETE, timer_timerCompleteHandler);\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > numTouchesRequired)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == 1)\n\t\t\t{\n\t\t\t\t_timer.reset();\n\t\t\t\t_timer.delay = maxTapDuration;\n\t\t\t\t_timer.start();\n\t\t\t}\n\t\t\t\n\t\t\tif (numTapsRequired > 1)\n\t\t\t{\n\t\t\t\tif (_tapCounter == 0)\n\t\t\t\t{\n\t\t\t\t\t// Save touch begin locations to check\n\t\t\t\t\t_touchBeginLocations.push(touch.location);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Quite a dirty check, but should work in most cases\n\t\t\t\t\tvar found:Boolean = false;\n\t\t\t\t\tfor each (var loc:Point in _touchBeginLocations)\n\t\t\t\t\t{\n\t\t\t\t\t\t// current touch should be near any previous one\n\t\t\t\t\t\tif (Point.distance(touch.location, loc) <= maxTapDistance)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!found)\n\t\t\t\t\t{\n\t\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == numTouchesRequired)\n\t\t\t{\n\t\t\t\t_numTouchesRequiredReached = true;\n\t\t\t\tupdateLocation();\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tif (slop >= 0 && touch.locationOffset.length > slop)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (!_numTouchesRequiredReached)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t\telse if (touchesCount == 0)\n\t\t\t{\n\t\t\t\t// reset flag for the next \"full press\" cycle\n\t\t\t\t_numTouchesRequiredReached = false;\n\t\t\t\t\n\t\t\t\t_tapCounter++;\n\t\t\t\t_timer.reset();\n\t\t\t\t\n\t\t\t\tif (_tapCounter == numTapsRequired)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.RECOGNIZED);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t_timer.delay = maxTapDelay;\n\t\t\t\t\t_timer.start();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Event handlers\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function timer_timerCompleteHandler(event:TimerEvent):void\n\t\t{\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/TransformGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\n\timport flash.geom.Point;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class TransformGesture extends AbstractContinuousGesture\n\t{\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP;\n\t\t\n\t\tprotected var _touch1:Touch;\n\t\tprotected var _touch2:Touch;\n\t\tprotected var _transformVector:Point;\n\t\t\n\t\t\n\t\tpublic function TransformGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _offsetX:Number = 0;\n\t\tpublic function get offsetX():Number\n\t\t{\n\t\t\treturn _offsetX;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _offsetY:Number = 0;\n\t\tpublic function get offsetY():Number\n\t\t{\n\t\t\treturn _offsetY;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _rotation:Number = 0;\n\t\tpublic function get rotation():Number\n\t\t{\n\t\t\treturn _rotation;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _scale:Number = 1;\n\t\tpublic function get scale():Number\n\t\t{\n\t\t\treturn _scale;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn TransformGesture;\n\t\t}\n\t\t\n\t\t\n\t\toverride public function reset():void\n\t\t{\n\t\t\t_touch1 = null;\n\t\t\t_touch2 = null;\n\t\t\t\n\t\t\tsuper.reset();\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > 2)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == 1)\n\t\t\t{\n\t\t\t\t_touch1 = touch;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_touch2 = touch;\n\t\t\t\t\n\t\t\t\t_transformVector = _touch2.location.subtract(_touch1.location);\n\t\t\t}\n\t\t\t\n\t\t\tupdateLocation();\n\t\t\t\n\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t{\n\t\t\t\t// notify that location (and amount of touches) has changed\n\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tvar prevLocation:Point = _location.clone();\n\t\t\tupdateLocation();\n\t\t\t\n\t\t\tvar currTransformVector:Point;\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tif (slop > 0 && touch.locationOffset.length < slop)\n\t\t\t\t{\n\t\t\t\t\t// Not recognized yet\n\t\t\t\t\tif (_touch2)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Recalculate _transformVector to avoid initial \"jump\" on recognize\n\t\t\t\t\t\t_transformVector = _touch2.location.subtract(_touch1.location);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif (_touch2 && !currTransformVector)\n\t\t\t{\n\t\t\t\tcurrTransformVector = _touch2.location.subtract(_touch1.location);\n\t\t\t}\n\t\t\t\n\t\t\t_offsetX = _location.x - prevLocation.x;\n\t\t\t_offsetY = _location.y - prevLocation.y;\n\t\t\tif (_touch2)\n\t\t\t{\n\t\t\t\t_rotation = Math.atan2(currTransformVector.y, currTransformVector.x) - Math.atan2(_transformVector.y, _transformVector.x);\n\t\t\t\t_scale = currTransformVector.length / _transformVector.length;\n\t\t\t\t_transformVector = _touch2.location.subtract(_touch1.location);\n\t\t\t}\n\t\t\t\n\t\t\tsetState(state == GestureState.POSSIBLE ? GestureState.BEGAN : GestureState.CHANGED);\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount == 0)\n\t\t\t{\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.ENDED);\n\t\t\t\t}\n\t\t\t\telse if (state == GestureState.POSSIBLE)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse// == 1\n\t\t\t{\n\t\t\t\tif (touch == _touch1)\n\t\t\t\t{\n\t\t\t\t\t_touch1 = _touch2;\n\t\t\t\t}\n\t\t\t\t_touch2 = null;\n\t\t\t\t\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tupdateLocation();\n\t\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function resetNotificationProperties():void\n\t\t{\n\t\t\tsuper.resetNotificationProperties();\n\t\t\t\n\t\t\t_offsetX = _offsetY = 0;\n\t\t\t_rotation = 0;\n\t\t\t_scale = 1;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/gestures/ZoomGesture.as",
    "content": "package org.gestouch.gestures\n{\n\timport org.gestouch.core.GestureState;\n\timport org.gestouch.core.Touch;\n\n\timport flash.geom.Point;\n\n\n\t/**\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class ZoomGesture extends AbstractContinuousGesture\n\t{\n\t\tpublic var slop:Number = Gesture.DEFAULT_SLOP;\n\t\tpublic var lockAspectRatio:Boolean = true;\n\t\t\n\t\tprotected var _touch1:Touch;\n\t\tprotected var _touch2:Touch;\n\t\tprotected var _transformVector:Point;\n\t\tprotected var _initialDistance:Number;\n\t\t\n\t\t\n\t\tpublic function ZoomGesture(target:Object = null)\n\t\t{\n\t\t\tsuper(target);\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _scaleX:Number = 1;\n\t\tpublic function get scaleX():Number\n\t\t{\n\t\t\treturn _scaleX;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _scaleY:Number = 1;\n\t\tpublic function get scaleY():Number\n\t\t{\n\t\t\treturn _scaleY;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Public methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride public function reflect():Class\n\t\t{\n\t\t\treturn ZoomGesture;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t// --------------------------------------------------------------------------\n\t\t//\n\t\t// Protected methods\n\t\t//\n\t\t// --------------------------------------------------------------------------\n\t\t\n\t\toverride protected function onTouchBegin(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount > 2)\n\t\t\t{\n\t\t\t\tfailOrIgnoreTouch(touch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tif (touchesCount == 1)\n\t\t\t{\n\t\t\t\t_touch1 = touch;\n\t\t\t}\n\t\t\telse// == 2\n\t\t\t{\n\t\t\t\t_touch2 = touch;\n\t\t\t\t\n\t\t\t\t_transformVector = _touch2.location.subtract(_touch1.location);\n\t\t\t\t_initialDistance = _transformVector.length;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchMove(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount < 2)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tvar currTransformVector:Point = _touch2.location.subtract(_touch1.location);\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tconst d:Number = currTransformVector.length - _initialDistance;\n\t\t\t\tconst absD:Number = d >= 0 ? d : -d;\n\t\t\t\tif (absD < slop)\n\t\t\t\t{\n\t\t\t\t\t// Not recognized yet\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (slop > 0)\n\t\t\t\t{\n\t\t\t\t\t// adjust _transformVector to avoid initial \"jump\"\n\t\t\t\t\tconst slopVector:Point = currTransformVector.clone();\n\t\t\t\t\tslopVector.normalize(_initialDistance + (d >= 0 ? slop : -slop));\n\t\t\t\t\t_transformVector = slopVector;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\tif (lockAspectRatio)\n\t\t\t{\n\t\t\t\t_scaleX *= currTransformVector.length / _transformVector.length;\n\t\t\t\t_scaleY = _scaleX;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_scaleX *= currTransformVector.x / _transformVector.x;\n\t\t\t\t_scaleY *= currTransformVector.y / _transformVector.y;\n\t\t\t}\n\t\t\t\n\t\t\t_transformVector.x = currTransformVector.x;\n\t\t\t_transformVector.y = currTransformVector.y;\n\t\t\t\n\t\t\tupdateLocation();\n\t\t\t\n\t\t\tif (state == GestureState.POSSIBLE)\n\t\t\t{\n\t\t\t\tsetState(GestureState.BEGAN);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function onTouchEnd(touch:Touch):void\n\t\t{\n\t\t\tif (touchesCount == 0)\n\t\t\t{\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.ENDED);\n\t\t\t\t}\n\t\t\t\telse if (state == GestureState.POSSIBLE)\n\t\t\t\t{\n\t\t\t\t\tsetState(GestureState.FAILED);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse//== 1\n\t\t\t{\n\t\t\t\tif (touch == _touch1)\n\t\t\t\t{\n\t\t\t\t\t_touch1 = _touch2;\n\t\t\t\t}\n\t\t\t\t_touch2 = null;\n\t\t\t\t\n\t\t\t\tif (state == GestureState.BEGAN || state == GestureState.CHANGED)\n\t\t\t\t{\n\t\t\t\t\tupdateLocation();\n\t\t\t\t\tsetState(GestureState.CHANGED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\toverride protected function resetNotificationProperties():void\n\t\t{\n\t\t\tsuper.resetNotificationProperties();\n\t\t\t\n\t\t\t_scaleX = _scaleY = 1;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/org/gestouch/input/NativeInputAdapter.as",
    "content": "package org.gestouch.input\n{\n\timport org.gestouch.core.IInputAdapter;\n\timport org.gestouch.core.TouchesManager;\n\timport org.gestouch.core.gestouch_internal;\n\n\timport flash.display.InteractiveObject;\n\timport flash.display.Stage;\n\timport flash.events.EventPhase;\n\timport flash.events.MouseEvent;\n\timport flash.events.TouchEvent;\n\timport flash.ui.Multitouch;\n\timport flash.ui.MultitouchInputMode;\n\n\n\t/**\n\t * @author Pavel fljot\n\t */\n\tpublic class NativeInputAdapter implements IInputAdapter\n\t{\n\t\tprotected static const MOUSE_TOUCH_POINT_ID:uint = 0;\n\t\t\n\t\tprotected var _stage:Stage;\n\t\tprotected var _explicitlyHandleTouchEvents:Boolean;\n\t\tprotected var _explicitlyHandleMouseEvents:Boolean;\n\t\t\n\t\tuse namespace gestouch_internal;\n\t\t\n\t\t\n\t\t{\n\t\t\tMultitouch.inputMode = MultitouchInputMode.TOUCH_POINT;\n\t\t}\n\t\t\n\t\t\n\t\tpublic function NativeInputAdapter(stage:Stage,\n\t\t\t\t\t\t\t\t\t\t   explicitlyHandleTouchEvents:Boolean = false,\n\t\t\t\t\t\t\t\t\t\t   explicitlyHandleMouseEvents:Boolean = false)\n\t\t{\n\t\t\tsuper();\n\t\t\t\n\t\t\tif (!stage)\n\t\t\t{\n\t\t\t\tthrow new ArgumentError(\"Stage must be not null.\");\n\t\t\t}\n\t\t\t\n\t\t\t_stage = stage;\n\t\t\t\n\t\t\t_explicitlyHandleTouchEvents = explicitlyHandleTouchEvents;\n\t\t\t_explicitlyHandleMouseEvents = explicitlyHandleMouseEvents;\n\t\t}\n\t\t\n\t\t\n\t\tprotected var _touchesManager:TouchesManager;\n\t\tpublic function set touchesManager(value:TouchesManager):void\n\t\t{\n\t\t\t_touchesManager = value;\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Public methods\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tpublic function init():void\n\t\t{\n\t\t\tif (Multitouch.supportsTouchEvents || _explicitlyHandleTouchEvents)\n\t\t\t{\n\t\t\t\t_stage.addEventListener(TouchEvent.TOUCH_BEGIN, touchBeginHandler, true);\n\t\t\t\t_stage.addEventListener(TouchEvent.TOUCH_BEGIN, touchBeginHandler, false);\n\t\t\t\t_stage.addEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, true);\n\t\t\t\t_stage.addEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, false);\n\t\t\t\t// Maximum priority to prevent event hijacking and loosing the touch\n\t\t\t\t_stage.addEventListener(TouchEvent.TOUCH_END, touchEndHandler, true, int.MAX_VALUE);\n\t\t\t\t_stage.addEventListener(TouchEvent.TOUCH_END, touchEndHandler, false, int.MAX_VALUE);\n\t\t\t}\n\t\t\t\n\t\t\tif (!Multitouch.supportsTouchEvents || _explicitlyHandleMouseEvents)\n\t\t\t{\n\t\t\t\t_stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, true);\n\t\t\t\t_stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false);\n\t\t\t}\n\t\t}\n\n\n\t\tpublic function onDispose():void\n\t\t{\n\t\t\t_touchesManager = null;\n\t\t\t\n\t\t\t_stage.removeEventListener(TouchEvent.TOUCH_BEGIN, touchBeginHandler, true);\n\t\t\t_stage.removeEventListener(TouchEvent.TOUCH_BEGIN, touchBeginHandler, false);\n\t\t\t_stage.removeEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, true);\n\t\t\t_stage.removeEventListener(TouchEvent.TOUCH_MOVE, touchMoveHandler, false);\n\t\t\t_stage.removeEventListener(TouchEvent.TOUCH_END, touchEndHandler, true);\n\t\t\t_stage.removeEventListener(TouchEvent.TOUCH_END, touchEndHandler, false);\n\t\t\t\n\t\t\t_stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, true);\n\t\t\t_stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false);\n\t\t\tunstallMouseListeners();\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Private methods\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function installMouseListeners():void\n\t\t{\n\t\t\t_stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);\n\t\t\t_stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false);\n\t\t\t// Maximum priority to prevent event hijacking\n\t\t\t_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true, int.MAX_VALUE);\n\t\t\t_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, int.MAX_VALUE);\n\t\t}\n\t\t\n\t\t\n\t\tprotected function unstallMouseListeners():void\n\t\t{\n\t\t\t_stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);\n\t\t\t_stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false);\n\t\t\t// Maximum priority to prevent event hijacking\n\t\t\t_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, true);\n\t\t\t_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false);\n\t\t}\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t//--------------------------------------------------------------------------\n\t\t//\n\t\t//  Event handlers\n\t\t//\n\t\t//--------------------------------------------------------------------------\n\t\t\n\t\tprotected function touchBeginHandler(event:TouchEvent):void\n\t\t{\n\t\t\t// We listen in EventPhase.CAPTURE_PHASE or EventPhase.AT_TARGET\n\t\t\t// (to catch on empty stage) phases only\n\t\t\tif (event.eventPhase == EventPhase.BUBBLING_PHASE)\n\t\t\t\treturn;\n\t\t\t\n\t\t\t_touchesManager.onTouchBegin(event.touchPointID, event.stageX, event.stageY, event.target as InteractiveObject);\n\t\t}\n\t\t\n\t\t\n\t\tprotected function touchMoveHandler(event:TouchEvent):void\n\t\t{\n\t\t\t// We listen in EventPhase.CAPTURE_PHASE or EventPhase.AT_TARGET\n\t\t\t// (to catch on empty stage) phases only\n\t\t\tif (event.eventPhase == EventPhase.BUBBLING_PHASE)\n\t\t\t\treturn;\n\t\t\t\n\t\t\t_touchesManager.onTouchMove(event.touchPointID, event.stageX, event.stageY);\n\t\t}\n\t\t\n\t\t\n\t\tprotected function touchEndHandler(event:TouchEvent):void\n\t\t{\n\t\t\t// We listen in EventPhase.CAPTURE_PHASE or EventPhase.AT_TARGET\n\t\t\t// (to catch on empty stage) phases only\n\t\t\tif (event.eventPhase == EventPhase.BUBBLING_PHASE)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tif (event.hasOwnProperty(\"isTouchPointCanceled\") && event[\"isTouchPointCanceled\"])\n\t\t\t{\n\t\t\t\t_touchesManager.onTouchCancel(event.touchPointID, event.stageX, event.stageY);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_touchesManager.onTouchEnd(event.touchPointID, event.stageX, event.stageY);\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprotected function mouseDownHandler(event:MouseEvent):void\n\t\t{\n\t\t\t// We listen in EventPhase.CAPTURE_PHASE or EventPhase.AT_TARGET\n\t\t\t// (to catch on empty stage) phases only\n\t\t\tif (event.eventPhase == EventPhase.BUBBLING_PHASE)\n\t\t\t\treturn;\n\t\t\t\n\t\t\tconst touchAccepted:Boolean = _touchesManager.onTouchBegin(MOUSE_TOUCH_POINT_ID, event.stageX, event.stageY, event.target as InteractiveObject);\n\t\t\t\n\t\t\tif (touchAccepted)\n\t\t\t{\n\t\t\t\tinstallMouseListeners();\t\t\t\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\tprotected function mouseMoveHandler(event:MouseEvent):void\n\t\t{\n\t\t\t// We listen in EventPhase.CAPTURE_PHASE or EventPhase.AT_TARGET\n\t\t\t// (to catch on empty stage) phases only\n\t\t\tif (event.eventPhase == EventPhase.BUBBLING_PHASE)\n\t\t\t\treturn;\n\t\t\t\n\t\t\t_touchesManager.onTouchMove(MOUSE_TOUCH_POINT_ID, event.stageX, event.stageY);\n\t\t}\n\t\t\n\t\t\n\t\tprotected function mouseUpHandler(event:MouseEvent):void\n\t\t{\n\t\t\t// We listen in EventPhase.CAPTURE_PHASE or EventPhase.AT_TARGET\n\t\t\t// (to catch on empty stage) phases only\n\t\t\tif (event.eventPhase == EventPhase.BUBBLING_PHASE)\n\t\t\t\treturn;\t\t\t\n\t\t\t\n\t\t\t_touchesManager.onTouchEnd(MOUSE_TOUCH_POINT_ID, event.stageX, event.stageY);\n\t\t\t\n\t\t\tif (_touchesManager.activeTouchesCount == 0)\n\t\t\t{\n\t\t\t\tunstallMouseListeners();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/input/TUIOInputAdapter.as",
    "content": "package org.gestouch.input\n{\n\timport org.gestouch.core.IInputAdapter;\n\timport org.gestouch.core.TouchesManager;\n\n\n\t/**\n\t * TODO: You can implement your own TUIO Input Adapter (and supply touchesManager with\n\t * touch info), but IMHO it is way easier to use NativeInputAdapter and any TUIO library\n\t * and manually dispatch native TouchEvents using DisplayObjectContainer#getObjectsUnderPoint()\n\t * \n\t * @see NativeInputAdapter\n\t * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html#getObjectsUnderPoint() DisplayObjectContainer#getObjectsUnderPoint() \n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class TUIOInputAdapter implements IInputAdapter\n\t{\n\t\tpublic function init():void\n\t\t{\n\t\t}\n\n\n\t\tpublic function onDispose():void\n\t\t{\n\t\t}\n\n\n\t\tpublic function set touchesManager(value:TouchesManager):void\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/org/gestouch/utils/GestureUtils.as",
    "content": "package org.gestouch.utils\n{\n\timport flash.geom.Point;\n\timport flash.system.Capabilities;\n\t/**\n\t * Set of constants.\n\t * \n\t * @author Pavel fljot\n\t */\n\tpublic class GestureUtils\n\t{\n\t\t/**\n\t\t * Precalculated coefficient used to convert 'inches per second' value to 'pixels per millisecond' value.\n\t\t */\n\t\tpublic static const IPS_TO_PPMS:Number = Capabilities.screenDPI * 0.001;\n\t\t/**\n\t\t * Precalculated coefficient used to convert radians to degress.\n\t\t */\n\t\tpublic static const RADIANS_TO_DEGREES:Number = 180 / Math.PI;\n\t\t/**\n\t\t * Precalculated coefficient used to convert degress to radians.\n\t\t */\n\t\tpublic static const DEGREES_TO_RADIANS:Number = Math.PI / 180;\n\t\t/**\n\t\t * Precalculated coefficient Math.PI * 2\n\t\t */\n\t\tpublic static const PI_DOUBLE:Number = Math.PI * 2;\n\t\tpublic static const GLOBAL_ZERO:Point = new Point();\n\t}\n}"
  },
  {
    "path": "version.properties",
    "content": "project.version = 0.4.6"
  }
]