[
  {
    "path": ".gitignore",
    "content": ".vscode/"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Jeremy Patrick Pacabis\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# react-native-svg-animations [![npm version](https://badge.fury.io/js/react-native-svg-animations.svg)](https://badge.fury.io/js/react-native-svg-animations)\n\n> SVG Animations wrapper for react-native. Based on examples from this project: https://github.com/ethantran/react-native-examples\n\n## Dependencies\n\n- `svg-path-properties`\n- `react-native-svg`\n\n## Installation\n\n```\nnpm i react-native-svg-animations --save\n```\nor\n```\nyarn add react-native-svg-animations\n```\n\n## Demo\n\n<table>\n  <tr>\n    <td>\n      <strong>AnimatedSVGPath</strong>\n    </td>\n    <td>\n      <strong>AnimatedSVGPaths</strong>\n    </td>\n  </tr>\n  <tr>\n    <td>\n      <img src=\"https://raw.githubusercontent.com/73R3WY/react-native-svg-animations/master/examples/HiSVG/hi_1.gif\" width=\"300\">\n    </td>\n    <td>\n      <img src=\"https://raw.githubusercontent.com/73R3WY/react-native-svg-animations/master/examples/IngenuityPreloaderSVG/preloader_1.gif\" width=\"300\">\n    </td>\n  </tr>\n</table>\n\n## Usage\n\nThis package contains wrapper components for displaying animated SVG in react-native, currently, this contains the following:\n\n- AnimatedSVGPath\n- AnimatedSVGPaths\n\n###### AnimatedSVGPath\n\nComponent to display a single animated SVG Path.\nSee <a href=\"https://github.com/73R3WY/react-native-svg-animations/tree/master/examples/HiSVG\">Hi example</a> for the complete implementation.\n\n<img src=\"https://raw.githubusercontent.com/73R3WY/react-native-svg-animations/master/examples/HiSVG/hi_2.gif\" width=\"300\">\n\n```javascript\nimport { AnimatedSVGPath } from \"react-native-svg-animations\";\n```\n\n...\n\n```javascript\n<View>\n  <AnimatedSVGPath\n    strokeColor={\"green\"}\n    duration={500}\n    strokeWidth={10}\n    strokeLinecap={\"round\"}\n    strokeDashArray={[42.76482137044271, 42.76482137044271]}\n    height={400}\n    width={400}\n    scale={0.75}\n    delay={100}\n    d={d}\n    loop={false}\n  />\n</View>\n```\n\nwhere the properties are:\n\n- `d` - the SVG Path to be animated. (required)\n- `strokeColor` - the color of the path stroke. (defaults to black)\n- `strokeWidth` - the thickness of the path stroke. (defaults to 1)\n- `strokeLinecap` - the shape to be used at the end of open subpaths when they are stroked. (defaults to butt)\n- `strokeDashArray` - the number and length of strokes. (defaults to total length obtained from properties of d)\n- `height` - the height of the base SVG. (defaults to screen viewport height)\n- `width` - the width of the base SVG. (defaults to screen viewport width)\n- `scale` - the scale of the output SVG based on the width and height of the base SVG. (defaults to 1.0 or 100%)\n- `delay` - time in `ms` before starting animation. (defaults to 1000ms or 1s)\n- `pause` - time in `ms` to pause at the end of the animation or at the half point of a rewound animation. (defaults 0)\n- `duration` - time in `ms` to complete the path drawing from starting point to ending point. (defaults to 1000ms or 1s)\n- `fill` - the color fill of the closed path. (defaults to none)\n- `loop` - whether the animation loops infinitely. (defaults to true)\n- `reverse` - Begins drawn and fades as you go . (defaults to false)\n- `rewind` - the path is rewound when it was complete. (defaults to false)\n\n###### AnimatedSVGPaths\n\nComponent to display a multiple animated SVG Paths.\nSee <a href=\"https://github.com/73R3WY/react-native-svg-animations/tree/master/examples/IngenuityPreloaderSVG\">Ingenuity preloader example</a> for the complete implementation.\n\n<img src=\"https://raw.githubusercontent.com/73R3WY/react-native-svg-animations/master/examples/IngenuityPreloaderSVG/preloader_2.gif\" width=\"300\">\n\n```javascript\nimport { AnimatedSVGPaths } from \"react-native-svg-animations\";\n```\n\n...\n\n```javascript\n<View>\n  <AnimatedSVGPaths\n    strokeColor={\"red\"}\n    strokeWidth={5}\n    duration={10000}\n    height={600}\n    width={600}\n    scale={0.5}\n    delay={100}\n    ds={ds}\n  />\n</View>\n```\n\nwhere the properties are:\n\n- `strokeColor` - the color of the path stroke. (defaults to black)\n- `strokeWidth` - the thickness of the path stroke. (defaults to 1)\n- `height` - the height of the base SVG. (defaults to screen viewport height)\n- `width` - the width of the base SVG. (defaults to screen viewport width)\n- `scale` - the scale of the output SVG based on the width and height of the base SVG. (defaults to 1.0 or 100%)\n- `delay` - time in `ms` before starting animation. (defaults to 1000ms or 1s)\n- `pause` - time in `ms` to pause at the end of the animation or at the half point of a rewound animation. (defaults 0)\n- `duration` - time in `ms` to complete the path drawing from starting point to ending point. (defaults to 1000ms or 1s)\n- `fill` - the color fill of the closed path. (defaults to none)\n- `loop` - whether the animation loops infinitely. (defaults to true)\n- `reverse` - Begins drawn and fades as you go . (defaults to false)\n- `rewind` - the path is rewound when it was complete. (defaults to false)\n- `sequential` - paths start to animate sequentially with the delay between them specified in the `delay` prop, and wait for the last one to finish before a new animation begins. (defaults to false)\n- `ds` - the SVG Paths to be animated, must be an array; either this or `customSvgProps` is required.\n- `customSvgProps` - an array of objects to define path properties; other properties will be overwritten by the values defined in these objects; either this or `ds` is required.\n  ```javascript\n  <AnimatedSVGPaths\n    //...\n    customSvgProps={[\n      {\n        d: \"M 10 10 C 20 20, 40 20, 50 10\",\n        strokeColor: 'blue',\n        strokeWidth: 1\n        //...\n      },\n      {\n        d: \"M 70 10 C 70 20, 110 20, 110 10\",\n        strokeColor: 'red',\n        strokeWidth: 3\n        //...\n      },\n    ]}\n    //...\n  />  \n  ```\n\n## TODO\n\n- Other animated SVG objects.\n\n## Contributing\n\n1. Fork it!\n2. Create your feature branch: `git checkout -b my-new-feature`\n3. Commit your changes: `git commit -am 'Add some feature'`\n4. Push to the branch: `git push origin my-new-feature`\n5. Submit a pull request :D\n\n## Contributors\n\nSpecial thanks to these contributors:\n\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/Mr-Bhardwa7\">\n          <img src=\"https://avatars.githubusercontent.com/u/40822939?v=3?s=100\" width=\"100px;\" alt=\"Mr-Bhardwa7\"/>\n          <br />\n          <sub><b>Mr-Bhardwa7</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/dimofte\">\n          <img src=\"https://avatars.githubusercontent.com/u/4060827?v=3?s=100\" width=\"100px;\" alt=\"dimofte\"/>\n          <br />\n          <sub><b>dimofte</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/jvt\">\n          <img src=\"https://avatars.githubusercontent.com/u/2718101?v=3?s=100\" width=\"100px;\" alt=\"jvt\"/>\n          <br />\n          <sub><b>jvt</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/b8ne\">\n          <img src=\"https://avatars.githubusercontent.com/u/19263633?v=3?s=100\" width=\"100px;\" alt=\"b8ne\"/>\n          <br />\n          <sub><b>b8ne</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/hovlev\">\n          <img src=\"https://avatars.githubusercontent.com/u/1330309?v=3?s=100\" width=\"100px;\" alt=\"hovlev\"/>\n          <br />\n          <sub><b>hovlev</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/qvick1pro\">\n          <img src=\"https://avatars.githubusercontent.com/u/12903197?v=3?s=100\" width=\"100px;\" alt=\"qvick1pro\"/>\n          <br />\n          <sub><b>qvick1pro</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/TristanTouchain\">\n          <img src=\"https://avatars.githubusercontent.com/u/36477156?v=3?s=100\" width=\"100px;\" alt=\"TristanTouchain\"/>\n          <br />\n          <sub><b>TristanTouchain</b></sub>\n        </a>\n      </td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/nitzanbener\">\n          <img src=\"https://avatars.githubusercontent.com/u/44496859?v=3?s=100\" width=\"100px;\" alt=\"nitzanbener\"/>\n          <br />\n          <sub><b>nitzanbener</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/muh-hamada\">\n          <img src=\"https://avatars.githubusercontent.com/u/56512406?v=3?s=100\" width=\"100px;\" alt=\"muh-hamada\"/>\n          <br />\n          <sub><b>muh-hamada</b></sub>\n        </a>\n      </td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\">\n        <a href=\"https://github.com/benomatis\">\n          <img src=\"https://avatars.githubusercontent.com/u/5822748?v=3?s=100\" width=\"100px;\" alt=\"benomatis\"/>\n          <br />\n          <sub><b>benomatis</b></sub>\n        </a>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n\n## License\n\nMIT\n"
  },
  {
    "path": "components/AnimatedPath/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { Animated, Easing } from 'react-native'\nimport { svgPathProperties } from 'svg-path-properties'\nimport { PathProps } from 'react-native-svg'\nimport Path from '../AnimatedSVG'\n\nexport interface AnimatedSvgPathProps {\n  d: string\n  strokeColor?: PathProps[`stroke`]\n  strokeWidth?: PathProps[`strokeWidth`]\n  strokeLinecap?: PathProps[`strokeLinecap`]\n  easing?: Animated.TimingAnimationConfig[`easing`]\n  fill?: PathProps[`fill`]\n  duration?: number\n  delay?: number\n  scale?: number\n  loop?: boolean\n  transform?: PathProps[`transform`]\n  reverse?: boolean\n  rewind?: boolean\n  pause?: number\n}\n\nconst AnimatedSvgPath: React.FC<AnimatedSvgPathProps> = ({\n  d,\n  strokeColor = 'black',\n  strokeWidth = 1,\n  strokeLinecap = 'butt',\n  easing = Easing.inOut(Easing.ease),\n  duration = 1000,\n  delay = 1000,\n  fill = 'none',\n  scale = 1,\n  loop = true,\n  transform = '',\n  reverse = false,\n  rewind = false,\n  pause = 0,\n}) => {\n  let loopCount = 0\n  const properties = new svgPathProperties(d)\n  const length = properties.getTotalLength()\n  const strokeDashoffset = new Animated.Value(!reverse ? length : 0)\n\n  const animate = () => {\n    strokeDashoffset.setValue(!reverse ? length : 0)\n    const animationsSequence = [].concat(\n      [\n        Animated.delay(delay * (loopCount && rewind ? 2 : 1)),\n        Animated.timing(strokeDashoffset, {\n          toValue: !reverse ? 0 : length,\n          duration: duration,\n          useNativeDriver: true,\n          easing,\n        }),\n      ],\n      pause\n        ? [Animated.delay(pause)]\n        : [],\n      rewind\n        ? [\n          Animated.timing(strokeDashoffset, {\n            toValue: !reverse ? length : 0,\n            duration: duration,\n            useNativeDriver: true,\n            easing,\n          }),\n        ]\n        : []\n    )\n\n    Animated.sequence(animationsSequence).start(() => {\n      if (loop) {\n        animate()\n      }\n    })\n\n    loopCount = 1\n  }\n\n  useEffect(() => {\n    animate()\n  }, [])\n\n  return (\n    <Path\n      strokeDasharray={[length, length]}\n      strokeDashoffset={strokeDashoffset}\n      strokeWidth={strokeWidth}\n      strokeLinecap={strokeLinecap}\n      stroke={strokeColor}\n      scale={scale}\n      fill={fill}\n      transform={transform}\n      d={d}\n    />\n  )\n}\n\nexport default AnimatedSvgPath\n"
  },
  {
    "path": "components/AnimatedSVG/index.tsx",
    "content": "import React, { Component, Ref } from 'react'\nimport { Path, PathProps } from 'react-native-svg'\n\nimport AnimatedSvg from '../../utils/AnimatedSVG'\n\ninterface AnimatedSvgPathBaseProps extends PathProps {\n  ref?: Ref<Path>\n}\n\nclass AnimatedSvgPathBase extends Component<AnimatedSvgPathBaseProps> {\n  #_component: Path | null = null\n\n  setNativeProps = (props: AnimatedSvgPathBaseProps = {}) => {\n    this.#_component && this.#_component.setNativeProps(props)\n  }\n\n  render() {\n    return (\n      <Path\n        ref={(component) => (this.#_component = component)}\n        {...this.props}\n      />\n    )\n  }\n}\n\nconst AnimatedSvgPath = AnimatedSvg(AnimatedSvgPathBase)\n\nexport default AnimatedSvgPath\n"
  },
  {
    "path": "components/AnimatedSVGPath/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport Svg, { PathProps } from 'react-native-svg'\nimport { Animated, Dimensions, Easing } from 'react-native'\nimport { svgPathProperties } from 'svg-path-properties'\nimport Path from '../AnimatedSVG'\n\nconst {\n  height: windowHeight,\n  width: windowWidth,\n} = Dimensions.get('window')\n\nexport interface AnimatedSVGPathProps {\n  d: string\n  strokeColor?: PathProps[`stroke`]\n  strokeWidth?: PathProps[`strokeWidth`]\n  strokeLinecap?: PathProps[`strokeLinecap`]\n  easing?: Animated.TimingAnimationConfig[`easing`]\n  fill?: PathProps[`fill`]\n  duration?: number\n  height?: number\n  delay?: number\n  width?: number\n  scale?: number\n  loop?: boolean\n  transform?: PathProps[`transform`]\n  reverse?: boolean\n  rewind?: boolean\n  strokeDasharray?: string[]\n  pause?: number\n}\n\nconst AnimatedSVGPath: React.FC<AnimatedSVGPathProps> = ({\n  d,\n  strokeColor = 'black',\n  strokeWidth = 1,\n  strokeLinecap = 'butt',\n  easing = Easing.inOut(Easing.ease),\n  duration = 1000,\n  delay = 1000,\n  fill = 'none',\n  scale = 1,\n  loop = true,\n  transform = '',\n  reverse = false,\n  rewind = false,\n  height = windowHeight,\n  width = windowWidth,\n  strokeDasharray,\n  pause = 0,\n}) => {\n  let loopCount = 0\n  const properties = new svgPathProperties(d)\n  const length = properties.getTotalLength()\n  const strokeDashoffset = new Animated.Value(!reverse ? length : 0)\n\n  const animate = () => {\n    strokeDashoffset.setValue(!reverse ? length : 0)\n    const animationsSequence = [].concat(\n      [\n        Animated.delay(delay * (loopCount ? 2 : 1)),\n        Animated.timing(strokeDashoffset, {\n          toValue: !reverse ? 0 : length,\n          duration: duration,\n          useNativeDriver: true,\n          easing: typeof easing === 'function' ? easing : Easing[easing],\n        }),\n      ],\n      pause\n        ? [Animated.delay(pause)]\n        : [],\n      rewind\n        ? [\n          Animated.timing(strokeDashoffset, {\n            toValue: !reverse ? length : 0,\n            duration: duration,\n            useNativeDriver: true,\n            easing: typeof easing === 'function' ? easing : Easing[easing],\n          }),\n        ]\n        : []\n    )\n\n    Animated.sequence(animationsSequence).start(() => {\n      if (loop) {\n        animate()\n      }\n    })\n\n    loopCount = 1\n  }\n\n  useEffect(() => {\n    animate()\n  }, [])\n\n\n  return (\n    <Svg height={height * scale + 5} width={width * scale + 5}>\n      <Path\n        strokeDasharray={strokeDasharray || [length, length]}\n        strokeDashoffset={strokeDashoffset}\n        strokeWidth={strokeWidth}\n        strokeLinecap={strokeLinecap}\n        stroke={strokeColor}\n        scale={scale}\n        fill={fill}\n        transform={transform}\n        d={d}\n      />\n    </Svg>\n  )\n}\n\nexport default AnimatedSVGPath\n"
  },
  {
    "path": "components/AnimatedSVGPaths/index.tsx",
    "content": "import React from 'react'\nimport Svg, { PathProps } from 'react-native-svg'\nimport { Dimensions } from 'react-native'\nimport Path from '../AnimatedPath'\nimport { AnimatedSVGPathProps } from '../AnimatedSVGPath'\n\nconst {\n  height: windowHeight,\n  width: windowWidth,\n} = Dimensions.get('window')\n\nexport type CustomSVGPathProps = AnimatedSVGPathProps\n\nexport interface AnimatedSvgPathsProps {\n  ds?: string[],\n  customSVGProps?: CustomSVGPathProps[]\n  strokeColor?: PathProps[`stroke`]\n  strokeWidth?: PathProps[`strokeWidth`]\n  fill?: PathProps[`fill`]\n  duration?: number\n  height?: number\n  delay?: number\n  width?: number\n  scale?: number\n  loop?: boolean\n  rewind?: boolean\n  pause?: number\n  sequential?: boolean\n}\n\nconst AnimatedSVGPaths: React.FC<AnimatedSvgPathsProps> = ({\n  ds = [],\n  customSVGProps = [],\n  strokeColor = 'black',\n  strokeWidth = 1,\n  duration = 1000,\n  delay = 1000,\n  fill = 'none',\n  scale = 1,\n  loop = true,\n  rewind = false,\n  pause = 0,\n  sequential = false,\n  height = windowHeight,\n  width = windowWidth,\n}) => {\n  const svgArray = ds.length > 0\n    ? ds\n    : customSVGProps.length > 0\n      ? customSVGProps\n      : []\n\n  const svgPaths = svgArray.map((d: string | CustomSVGPathProps, index: number) => {\n    let pathProps: AnimatedSVGPathProps & {\n      key: number\n    } = {\n      key: index,\n      strokeWidth,\n      strokeColor,\n      duration,\n      delay: sequential ? index * delay : delay,\n      scale,\n      fill,\n      loop,\n      rewind,\n      d: '',\n      height,\n      width,\n    }\n\n    if (typeof d === 'string') {\n      pathProps.d = d\n    } else {\n      Object.assign(pathProps, d)\n    }\n\n    if (sequential) {\n      pathProps.pause = (svgArray.length - 1 - index) * delay * (rewind ? 2 : 1)\n    }\n\n    if (pause) {\n      pathProps.pause = pause\n    }\n\n    return (\n      <Path {...pathProps}/>\n    )\n  })\n\n  return (\n    <Svg height={height * scale + 5} width={width * scale + 5}>\n      {svgPaths}\n    </Svg>\n  )\n}\n\nexport default AnimatedSVGPaths\n"
  },
  {
    "path": "examples/HiSVG/d.js",
    "content": "export default 'M366.2,204.2c-9.8,0-15-5.6-15-15.1V77.2h-85v28h19.5c9.8,0,8.5,2.1,8.5,11.6v72.4c0,9.5,0.5,15.1-9.3,15.1H277h-20.7c-8.5,0-14.2-4.1-14.2-12.9V52.4c0-8.5,5.7-12.3,14.2-12.3h18.8v-28h-127v28h18.1c8.5,0,9.9,2.1,9.9,8.9v56.1h-75V53.4c0-11.5,8.6-13.3,17-13.3h11v-28H2.2v28h26c8.5,0,12,2.1,12,7.9v142.2c0,8.5-3.6,13.9-12,13.9h-21v33h122v-33h-11c-8.5,0-17-4.1-17-12.2v-57.8h75v58.4c0,9.1-1.4,11.6-9.9,11.6h-18.1v33h122.9h5.9h102.2v-33H366.2z';"
  },
  {
    "path": "examples/HiSVG/index.js",
    "content": "import React, {\n  Component,\n} from 'react';\nimport {\n  View,\n} from 'react-native';\n\nimport AnimatedSVGPath from '../../components/AnimatedSVGPath';\nimport d from './d';\n\nexport default class HiSVG extends Component {\n  render() {\n    return (\n      <View style={{ marginTop: 40 }}>\n        <AnimatedSVGPath\n          strokeColor={\"pink\"}\n          duration={2500}\n          strokeWidth={5}\n          height={400}\n          width={400}\n          scale={0.5}\n          delay={500}\n          d={d}\n        />\n      </View>\n    );\n  }\n}"
  },
  {
    "path": "examples/IngenuityPreloaderSVG/d.js",
    "content": "export default preloaderLines = [\n  'M498.465,1L1,288.188',\n  'M600.984,288.188L103.53,1',\n  'M462.988,601V1',\n  'M107.176,601l493.651-285',\n  'M1,315.91L494.822,601',\n  'M139,1v600',\n  'M1,322.827L558.475,1',\n  'M43.537,1L601,322.844',\n  'M432.986,1v600l0,0',\n  'M600.828,281.357L600.828,281.357L47.172,601',\n  'M554.82,601L1,281.268',\n  'M169,601V1',\n  'M300.581,288.648c-33.954,0-61.577-27.622-61.577-61.574c0-33.952,27.624-61.573,61.577-61.573c33.952,0,61.573,27.622,61.573,61.573C362.154,261.026,334.533,288.648,300.581,288.648z',\n  'M300.582,318.592c-50.466,0-91.522-41.055-91.522-91.518c0-50.463,41.058-91.517,91.522-91.517c50.462,0,91.517,41.055,91.517,91.517C392.099,277.537,351.044,318.592,300.582,318.592z',\n  'M299.774,441.807c-33.953,0-61.576-27.625-61.576-61.58c0-33.953,27.623-61.578,61.576-61.578c33.954,0,61.575,27.625,61.575,61.578C361.351,414.182,333.728,441.807,299.774,441.807z',\n  'M299.774,471.807c-50.494,0-91.574-41.083-91.574-91.58c0-50.496,41.08-91.578,91.574-91.578c50.495,0,91.571,41.082,91.571,91.578C391.349,430.724,350.269,471.807,299.774,471.807z',\n  'M1,303.598h599.828',\n  'M303,1v601',\n  'M1,1h599.828v600H1V1z'\n];"
  },
  {
    "path": "examples/IngenuityPreloaderSVG/index.js",
    "content": "import React, {\n  Component\n} from 'react';\nimport {\n  View\n} from 'react-native';\nimport ds from './d';\nimport AnimatedSVGPaths from '../../components/AnimatedSVGPaths';\n\nclass IngenuityPreloaderSVG extends Component {\n  render() {\n    return (\n      <View>\n        <AnimatedSVGPaths\n          strokeColor={\"orange\"}\n          strokeWidth={2.5}\n          duration={1000}\n          height={600}\n          width={600}\n          scale={0.5}\n          delay={100}\n          ds={ds}\n        />\n      </View>\n    );\n  }\n}\n\nexport default IngenuityPreloaderSVG;"
  },
  {
    "path": "index.js",
    "content": "import AnimatedSVGPath from './components/AnimatedSVGPath';\nimport AnimatedSVGPaths from './components/AnimatedSVGPaths';\n\n/* Export ==================================================================== */\n\nmodule.exports = {\n  AnimatedSVGPath: AnimatedSVGPath,\n  AnimatedSVGPaths: AnimatedSVGPaths,\n}"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-native-svg-animations\",\n  \"version\": \"1.0.0\",\n  \"description\": \"SVG Animations wrapper for react-native.\",\n  \"main\": \"index.js\",\n  \"directories\": {\n    \"example\": \"examples\"\n  },\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:73R3WY/react-native-svg-animations.git\"\n  },\n  \"keywords\": [\n    \"react-native\",\n    \"svg\",\n    \"animations\"\n  ],\n  \"author\": \"Jeremy Patrick Pacabis <jeremy@ingenuity.ph> (https://ingenuity.ph)\",\n  \"license\": \"ISC\",\n  \"bugs\": {\n    \"url\": \"https://github.com/73R3WY/react-native-svg-animations/issues\"\n  },\n  \"homepage\": \"https://github.com/73R3WY/react-native-svg-animations\",\n  \"dependencies\": {\n    \"color\": \"^4.2.3\",\n    \"react-native-svg\": \"^14.1.0\",\n    \"svg-path-properties\": \"^1.0.3\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.20.0\"\n  }\n}\n"
  },
  {
    "path": "utils/AnimatedListener/index.js",
    "content": "// @flow\nimport { Animated } from 'react-native';\n\ntype ResultArray = {\n  values: any[],\n  listeners: any[]\n};\n\ntype ResultObject = {\n  values: Object,\n  listeners: Object\n};\n\ntype ResultAnimated = {\n  values: number | string,\n  listeners: string\n};\n\ntype ResultOther = {\n  values: any\n};\n\ntype RecResult = ResultArray | ResultObject;\n\ntype Result = RecResult | ResultAnimated | ResultOther;\nexport type AnimatedListener = Result;\n\ntype AnimatedValue = typeof Animated.Value | typeof Animated.Interpolation;\n\n/**\n * Iterates object keys to find Animated objects to add listeners to and returns an object of values and listeners. The values field will be shaped identically to the passed in object with the Animated objects replaced with the value from __getValue at the time it was called.\n */\nfunction recursiveListen(\n  object,\n  accumulator: ResultArray | ResultObject,\n  accIndex: number,\n  cb: Function\n): RecResult {\n  if (Array.isArray(object)) {\n    let initialValue = new AnimatedTracker([], []);\n    return object.reduce(\n      (previousValue, currentValue, currentIndex, array) => {\n        const result = recursiveListen(\n          currentValue,\n          previousValue.values,\n          currentIndex,\n          cb\n        );\n        previousValue.values[currentIndex] = result.values;\n        previousValue.listeners[currentIndex] = result.listeners;\n        return previousValue;\n      },\n      initialValue\n    );\n  }\n  if (\n    object instanceof Animated.Value ||\n    object instanceof Animated.Interpolation\n  ) {\n    const id = addListenerForAnimated(object, accumulator, accIndex, cb);\n    return new AnimatedTracker(\n      object.__getValue(),\n      new ListenerTracker(id, object)\n    );\n  }\n  if (typeof object === 'object' && object !== null) {\n    let initialValue = new AnimatedTracker({}, {});\n    return Object.keys(object).reduce((previousValue, currentValue) => {\n      const value = object[currentValue];\n      const result = recursiveListen(\n        value,\n        previousValue.values,\n        currentValue,\n        cb\n      );\n      previousValue.values[currentValue] = result.values;\n      previousValue.listeners[currentValue] = result.listeners;\n      return previousValue;\n    }, initialValue);\n  }\n  return new AnimatedTracker(object);\n}\nfunction addListenerForAnimated(\n  animatedValue: AnimatedValue,\n  accumulator: ResultArray | ResultObject,\n  accIndex: number,\n  cb: Function\n) {\n  const addListener = animatedValue._parent\n      ? animatedValue._parent.addListener.bind(animatedValue._parent)\n      : animatedValue.addListener.bind(animatedValue);\n  const interpolator = animatedValue._interpolation;\n  let callback = e => e;\n  if (interpolator) {\n    callback = _value => interpolator(_value);\n  }\n  let prevCallback = callback;\n  callback = e => {\n    const value = prevCallback(e.value);\n    accumulator[accIndex] = value;\n    cb();\n  };\n  return addListener(callback);\n}\nexport function listen(object: Object | any[], cb: Function): Result {\n    return recursiveListen(object, null, null, cb);\n}\n\n/**\n * Iterates object keys to find a ListenerTracker with an Animated object and listener id to remove\n */\nfunction recursiveRemoveListeners(listeners: Object | any[]) {\n  if (Array.isArray(listeners)) {\n    listeners.forEach((listener, index) =>\n      recursiveRemoveListeners(listener)\n    );\n  } else if (listeners instanceof ListenerTracker) {\n    const id = listeners.id;\n    const object = listeners.object;\n    object._parent\n        ? object._parent.removeListener(id)\n        : object.removeListener(id);\n  } else if (typeof listeners === 'object' && listeners !== null) {\n    Object.keys(listeners).forEach(key =>\n      recursiveRemoveListeners(listeners[key])\n    );\n  }\n}\nexport function removeListeners(listeners: Object | any[] | AnimatedTracker) {\n  if (listeners instanceof AnimatedTracker) {\n    recursiveRemoveListeners(listeners.listeners);\n  } else {\n    recursiveRemoveListeners(listeners);\n  }\n}\n\nclass ListenerTracker {\n  id: string;\n  object: Animated.Value | Animated.Interpolation;\n  constructor(id: string, object: Animated.Value | Animated.Interpolation) {\n    this.id = id;\n    this.object = object;\n  }\n}\n\nclass AnimatedTracker {\n  values: any[] | Object | number | string;\n  listeners: ?(ListenerTracker | ListenerTracker[] | Object);\n  constructor(\n    values?: any[] | Object | string,\n    listeners?: ListenerTracker | ListenerTracker[] | Object\n  ) {\n    this.values = values;\n    this.listeners = listeners;\n  }\n}"
  },
  {
    "path": "utils/AnimatedSVG/index.js",
    "content": "import {\n  Animated,\n} from 'react-native';\nimport AnimatedSVGBrush from '../AnimatedSVGBrush';\nimport AnimatedSVGPropString from '../AnimatedSVGPropString';\nimport AnimatedSVGState from '../AnimatedSVGState';\nimport AnimatedSVGTransform from '../AnimatedSVGTransform';\n\nfunction AnimatedSVG (Component, {\n  state, propString, keepXY\n} = {}) {\n  Component = AnimatedSVGState(Component, state);\n  Component = AnimatedSVGBrush(Component);\n  Component = AnimatedSVGPropString(Component, propString);\n  Component = AnimatedSVGTransform(Component, { keepXY });\n  Component = Animated.createAnimatedComponent(Component);\n  return Component;\n}\n\nexport default AnimatedSVG;"
  },
  {
    "path": "utils/AnimatedSVGBrush/index.js",
    "content": "// @flow\n/**\n * Problem: Color props such as fill and stroke cannot be animated through setNativeProps. They can be animated through state, but setNativeProps is better\n * Solution: Extract brush, update propList (does not seem to do anything but to be consistent extractProps I did it anyway)\n */\nimport React, { Component } from 'react';\nimport Color from 'color';\nimport pick from 'lodash/pick';\n\nimport { listen, removeListeners } from '../AnimatedListener';\nimport type { AnimatedListener } from '../AnimatedListener';\n\n// https://github.com/react-native-community/react-native-svg/blob/master/lib/extract/extractBrush.js\nconst patternReg = /^url\\(#(.+?)\\)$/;\nfunction extractBrush(colorOrBrush) {\n  if (colorOrBrush === 'none' || !colorOrBrush) {\n    return null;\n  }\n  try {\n    let matched = colorOrBrush.match(patternReg);\n    // brush\n    if (matched) {\n      return [1, matched[1]];\n      //todo:\n    } else { // solid color\n      let [r, g, b, a = 1] = Color(colorOrBrush).rgb().array();\n      return [0, r / 255, g / 255, b / 255, a];\n    }\n  } catch (err) {\n    console.warn(`\"${colorOrBrush}\" is not a valid color or brush`);\n    return null;\n  }\n}\n\nconst fillKeys = ['fill', 'fillOpacity', 'fillRule'];\nconst strokeKeys = [\n  'stroke',\n  'strokeWidth',\n  'strokeOpacity',\n  'strokeDasharray',\n  'strokeDashoffset',\n  'strokeLinecap',\n  'strokeLinejoin',\n  'strokeMiterlimit'\n];\n\nfunction getPropList(nextProps, prevProps) {\n  let propList = [];\n  fillKeys.forEach(name => {\n    if (nextProps.hasOwnProperty(name) || prevProps.hasOwnProperty(name)) {\n      propList.push(name);\n    }\n  });\n  strokeKeys.forEach(name => {\n    if (nextProps.hasOwnProperty(name) || prevProps.hasOwnProperty(name)) {\n      propList.push(name);\n    }\n  });\n  return propList;\n}\n\nconst separator = /\\s*,\\s*/;\nfunction getStrokeDasharray(strokeDasharray) {\n  if (typeof strokeDasharray === 'string') {\n    strokeDasharray = strokeDasharray.split(separator).map(dash => +dash);\n  }\n  if (strokeDasharray && strokeDasharray.length === 1) {\n    strokeDasharray.push(strokeDasharray[0]);\n  }\n  // have to clone array to allow animation with mutable changes\n  return strokeDasharray ? [...strokeDasharray] : strokeDasharray;\n}\n\nfunction getStrokeDashoffset(nextProps, prevProps) {\n  const strokeDasharray =\n    getStrokeDasharray(nextProps.strokeDasharray) ||\n    getStrokeDasharray(prevProps.strokeDasharray);\n  return strokeDasharray\n    ? +nextProps.strokeDashoffset || +prevProps.strokeDashoffset || 0\n    : null;\n}\n\nconst KEYS = ['fill', 'stroke', 'strokeDashoffset'];\n\nexport default function SvgBrushFix(WrappedComponent) {\n  return class extends Component {\n    strokeDasharray: AnimatedListener;\n    constructor(props) {\n      super(props);\n      this.updateCache(props);\n      this.strokeDasharray = listen(props.strokeDasharray, _ =>\n        this.setNativeProps({ updateStrokeDasharray: true })\n      );\n    }\n    updateCache(props) {\n      this.prevProps = pick(props, KEYS);\n    }\n    setNativeProps = props => {\n      props.propList = getPropList(props, this.prevProps);\n      if (props.fill) {\n        props.fill = extractBrush(props.fill);\n      }\n      if (props.stroke) {\n        props.stroke = extractBrush(props.stroke);\n      }\n      if (props.updateStrokeDasharray || props.strokeDashoffset) {\n        props.strokeDasharray = getStrokeDasharray(\n          this.strokeDasharray.values\n        );\n        props.strokeDashoffset = getStrokeDashoffset(\n          props,\n          this.prevProps\n        );\n      }\n      this._component && this._component.setNativeProps(props);\n    };\n    componentDidUpdate(prevProps) {\n      this.updateCache(prevProps);\n      if (this.props.strokeDasharray !== prevProps.strokeDasharray) {\n        removeListeners(this.strokeDasharray);\n        this.strokeDasharray = listen(prevProps.strokeDasharray, _ =>\n          this.setNativeProps({ updateStrokeDasharray: true }));\n      }\n    }\n    componentWillUnmount() {\n      removeListeners(this.strokeDasharray);\n    }\n    render() {\n      const strokeDasharray = getStrokeDasharray(\n        this.strokeDasharray.values\n      );\n      return (\n        <WrappedComponent\n          ref={component => (this._component = component)}\n          {...this.props}\n          strokeDasharray={strokeDasharray}\n        />\n      );\n    }\n  };\n}"
  },
  {
    "path": "utils/AnimatedSVGPropString/index.js",
    "content": "import React, { Component } from 'react';\n\n/**\n * Problem: Props cannot be animated, too many times you have to do val.toString() in setNativeProps\n * Solution: Use a higher order component to do that for you\n */\n\nconst KEYS = [\n  'strokeWidth', 'strokeOpacity', 'fillOpacity'\n];\n\nexport default function SvgPropStringFix(WrappedComponent, propKeys = []) {\n  propKeys = [...KEYS, ...propKeys];\n  return class extends Component {\n    setNativeProps = (props) => {\n      propKeys.reduce((acc, key) => {\n        const val = props[key];\n        if (val != null) {\n          acc[key] = val.toString();\n        }\n        return acc;\n      }, props);\n      this._component && this._component.setNativeProps(props);\n    }\n    render() {\n      return (\n        <WrappedComponent\n          ref={component => (this._component = component)}\n          {...this.props}\n        />\n      );\n    }\n  };\n}"
  },
  {
    "path": "utils/AnimatedSVGState/index.js",
    "content": "import React, { Component } from 'react';\nimport omit from 'lodash/omit';\n\n/**\n * Problem: Some props cannot be animated through setNativeProps\n * Solution: Use state for those and use setNativeProps for the rest\n */\n\nfunction createState(props, keys) {\n  return keys.reduce((acc, key) => {\n    const value = props[key];\n    if (value != null) {\n      acc[key] = value;\n    }\n    return acc;\n  }, {});\n}\n\nexport default function SvgStateFix(WrappedComponent, propToStateKeys = [], { cancelSetNativeProps } = {}) {\n  return class extends Component {\n    state = createState(this.props, propToStateKeys);\n    setNativeProps = (props) => {\n      if (!cancelSetNativeProps) {\n        const nativeProps = omit(props, propToStateKeys);\n        this._component && this._component.setNativeProps(nativeProps);\n      }\n      const newState = createState(props, propToStateKeys);\n      this.setState(newState);\n    }\n    render() {\n      return (\n        <WrappedComponent\n          ref={component => (this._component = component)}\n          {...this.props}\n          {...this.state}\n        />\n      );\n    }\n  };\n}"
  },
  {
    "path": "utils/AnimatedSVGTransform/index.js",
    "content": "import React, { Component } from 'react';\nimport omit from 'lodash/omit';\nimport pick from 'lodash/pick';\nimport Matrix2D from '../Matrix2D';\n\n/**\n * Problem: Animating transform props is not easy\n * Solution: Use Animated.ValueXY in universal props, create matrix when ever transform props change, use setNativeProps\n * BUG: Using Animated.ValueXY does not work for some reason\n */\n\n// https://github.com/react-native-community/react-native-svg/blob/master/lib/extract/extractTransform.js\n// modified to deal with nextProps and prevProps situations with both static props on this.props and dynamic props passing through setNativeProps\nfunction _universal2axis(universal, axisX, axisY, defaultValue) {\n  let x;\n  let y;\n  if (typeof universal === 'object') {\n    x = universal.x;\n    y = universal.y;\n  } else if (typeof universal === 'number') {\n    x = y = universal;\n  }\n\n  axisX = +axisX;\n  if (!isNaN(axisX)) {\n    x = axisX;\n  }\n\n  axisY = +axisY;\n  if (!isNaN(axisY)) {\n    y = axisY;\n  }\n\n  return [x || defaultValue || 0, y || defaultValue || 0];\n}\n\nfunction universal2axis(key, nextProps, prevProps, defaultValue) {\n  let [nextX, nextY] = _universal2axis(nextProps[key], nextProps[key + 'X'], nextProps[key + 'Y']);\n  let [prevX, prevY] = _universal2axis(prevProps[key], prevProps[key + 'X'], prevProps[key + 'Y'], defaultValue);\n  return [nextX || prevX, nextY || prevY];\n}\n\nfunction createTransformObject(nextProps, prevProps) {\n  const [originX, originY] = universal2axis('origin', nextProps, prevProps);\n  const [scaleX, scaleY] = universal2axis('scale', nextProps, prevProps, 1);\n  const [skewX, skewY] = universal2axis('skew', nextProps, prevProps);\n  const [translateX, translateY] = universal2axis('translate', nextProps, prevProps);\n  const x = translateX || nextProps.x || prevProps.x || 0;\n  const y = translateY || nextProps.y || prevProps.y || 0;\n  const rotation = +nextProps.rotation || +nextProps.rotate || +prevProps.rotation || +prevProps.rotate || 0;\n  return {\n    rotation,\n    originX,\n    originY,\n    scaleX,\n    scaleY,\n    skewX,\n    skewY,\n    x,\n    y\n  };\n}\n\nlet pooledMatrix = new Matrix2D();\n\nfunction createTransformMatrix(props, transform) {\n  pooledMatrix.reset();\n  appendTransform(props);\n\n  if (transform) {\n    appendTransform(transform);\n  }\n\n  return pooledMatrix.toArray();\n}\n\nfunction appendTransform(transform) {\n  pooledMatrix\n    .appendTransform(\n    transform.x + transform.originX,\n    transform.y + transform.originY,\n    transform.scaleX, transform.scaleY,\n    transform.rotation,\n    transform.skewX,\n    transform.skewY,\n    transform.originX,\n    transform.originY\n  );\n}\n\nconst UNIVERSAL_KEYS = ['origin', 'scale', 'skew', 'translate'];\nconst KEYS = [...UNIVERSAL_KEYS, 'originX', 'originY', 'scaleX', 'scaleY', 'skewX', 'skewY', 'translateX', 'translateY', 'x', 'y', 'rotation', 'rotate'];\n\nexport default function SvgTransformFix(WrappedComponent, { keepXY } = {}) {\n  return class extends Component {\n    prevProps = pick(this.props, KEYS)\n    setNativeProps = (props) => {\n      // if some transform key exists in props, create a new matrix\n      if (KEYS.some((key, index) => props[key] != null)) {\n        const matrix = createTransformMatrix(createTransformObject(props, this.prevProps));\n        let x, y;\n        // some components like rect need these still\n        if (keepXY) {\n          x = props.x && props.x.toString();\n          y = props.y && props.y.toString();\n        }\n        // remove transform props since they are moved into matrix prop\n        props = omit(props, KEYS);\n        props.matrix = matrix;\n        props.x = x;\n        props.y = y;\n        // cache dynamic prop values since you need them to generate an accurate matrix\n        this.prevProps = Object.assign(this.prevProps, pick(props, KEYS));\n      }\n      this._component && this._component.setNativeProps(props);\n    }\n    render() {\n      return (\n        <WrappedComponent\n          ref={component => (this._component = component)}\n          {...this.props}\n        />\n      );\n    }\n  };\n}"
  },
  {
    "path": "utils/Matrix2D/index.ts",
    "content": "/**\n * based on\n * https://github.com/CreateJS/EaselJS/blob/631cdffb85eff9413dab43b4676f059b4232d291/src/easeljs/geom/Matrix2D.js\n */\nconst DEG_TO_RAD = Math.PI / 180\n\n/**\n * Represents an affine transformation matrix, and provides tools for constructing and concatenating matrices.\n *\n * This matrix can be visualized as:\n *\n * \t[ a  c  tx\n * \t  b  d  ty\n * \t  0  0  1  ]\n *\n * Note the locations of b and c.\n *\n * @class Matrix2D\n * @param {Number} [a=1] Specifies the a property for the new matrix.\n * @param {Number} [b=0] Specifies the b property for the new matrix.\n * @param {Number} [c=0] Specifies the c property for the new matrix.\n * @param {Number} [d=1] Specifies the d property for the new matrix.\n * @param {Number} [tx=0] Specifies the tx property for the new matrix.\n * @param {Number} [ty=0] Specifies the ty property for the new matrix.\n * @constructor\n **/\nexport default class Matrix2D {\n  constructor(a, b, c, d, tx, ty) {\n    this.setTransform(a, b, c, d, tx, ty)\n\n    // public properties:\n    // assigned in the setValues method.\n    /**\n     * Position (0, 0) in a 3x3 affine transformation matrix.\n     * @property a\n     * @type Number\n     **/\n\n    /**\n     * Position (0, 1) in a 3x3 affine transformation matrix.\n     * @property b\n     * @type Number\n     **/\n\n    /**\n     * Position (1, 0) in a 3x3 affine transformation matrix.\n     * @property c\n     * @type Number\n     **/\n\n    /**\n     * Position (1, 1) in a 3x3 affine transformation matrix.\n     * @property d\n     * @type Number\n     **/\n\n    /**\n     * Position (2, 0) in a 3x3 affine transformation matrix.\n     * @property tx\n     * @type Number\n     **/\n\n    /**\n     * Position (2, 1) in a 3x3 affine transformation matrix.\n     * @property ty\n     * @type Number\n     **/\n  }\n\n  /**\n   * Set current matrix to new absolute matrix.\n   * @method setTransform\n   * @param {Number} [a=1] Specifies the a property for the new matrix.\n   * @param {Number} [b=0] Specifies the b property for the new matrix.\n   * @param {Number} [c=0] Specifies the c property for the new matrix.\n   * @param {Number} [d=1] Specifies the d property for the new matrix.\n   * @param {Number} [tx=0] Specifies the tx property for the new matrix.\n   * @param {Number} [ty=0] Specifies the ty property for the new matrix.\n   * @return {Matrix2D} This instance. Useful for chaining method calls.\n   */\n  setTransform = function(a, b, c, d, tx, ty) {\n    /*eslint eqeqeq:0*/\n    this.a = a == null ? 1 : a\n    this.b = b || 0\n    this.c = c || 0\n    this.d = b == null ? 1 : d\n    this.tx = tx || 0\n    this.ty = ty || 0\n    return this\n  }\n\n  /**\n   * Reset current matrix to an identity matrix.\n   * @method reset\n   * @return {Matrix2D} This matrix. Useful for chaining method calls.\n   **/\n  reset = function() {\n    this.a = this.d = 1\n    this.b = this.c = this.tx = this.ty = 0\n    return this\n  }\n\n  /**\n   * Returns an array with current matrix values.\n   * @method toArray\n   * @return {Array} an array with current matrix values.\n   **/\n  toArray = function() {\n    return [this.a, this.b, this.c, this.d, this.tx, this.ty]\n  }\n\n  /**\n   * Copies all properties from the specified matrix to this matrix.\n   * @method copy\n   * @param {Matrix2D} matrix The matrix to copy properties from.\n   * @return {Matrix2D} This matrix. Useful for chaining method calls.\n   */\n  copy = function(matrix) {\n    return this.setTransform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty)\n  }\n\n  /**\n   * Clones current instance and returning a new matrix.\n   * @method clone\n   * @return {Matrix2D} a clone of the Matrix2D instance.\n   **/\n  clone = function() {\n    return new Matrix2D(this.a, this.b, this.c, this.d, this.tx, this.ty)\n  }\n\n  /**\n   * Prepends the specified matrix properties to this matrix.\n   * This is the equivalent of multiplying `(specified matrix) * (this matrix)`.\n   * All parameters are required.\n   * @method prepend\n   * @param {Number} a\n   * @param {Number} b\n   * @param {Number} c\n   * @param {Number} d\n   * @param {Number} tx\n   * @param {Number} ty\n   * @return {Matrix2D} This matrix. Useful for chaining method calls.\n   **/\n  prepend = function(a, b, c, d, tx, ty) {\n    var a1 = this.a\n    var c1 = this.c\n    var tx1 = this.tx\n\n    this.a  = a * a1 + c * this.b\n    this.b  = b * a1 + d * this.b\n    this.c  = a * c1 + c * this.d\n    this.d  = b * c1 + d * this.d\n    this.tx = a * tx1 + c * this.ty + tx\n    this.ty = b * tx1 + d * this.ty + ty\n    return this\n  }\n\n  /**\n   * Appends the specified matrix properties to this matrix. All parameters are required.\n   * This is the equivalent of multiplying `(this matrix) * (specified matrix)`.\n   * @method append\n   * @param {Number} a\n   * @param {Number} b\n   * @param {Number} c\n   * @param {Number} d\n   * @param {Number} tx\n   * @param {Number} ty\n   * @return {Matrix2D} This matrix. Useful for chaining method calls.\n   **/\n  append = function(a, b, c, d, tx, ty) {\n    var a1 = this.a\n    var b1 = this.b\n    var c1 = this.c\n    var d1 = this.d\n    if (a !== 1 || b !== 0 || c !== 0 || d !== 1) {\n      this.a  = a1 * a + c1 * b\n      this.b  = b1 * a + d1 * b\n      this.c  = a1 * c + c1 * d\n      this.d  = b1 * c + d1 * d\n    }\n    this.tx = a1 * tx + c1 * ty + this.tx\n    this.ty = b1 * tx + d1 * ty + this.ty\n    return this\n  }\n\n  /**\n   * Generates matrix properties from the specified display object transform properties, and appends them to this matrix.\n   * For example, you can use this to generate a matrix representing the transformations of a display object:\n   *\n   * \tvar mtx = new createjs.Matrix2D()\n   * \tmtx.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation)\n   * @method appendTransform\n   * @param {Number} x\n   * @param {Number} y\n   * @param {Number} scaleX\n   * @param {Number} scaleY\n   * @param {Number} rotation\n   * @param {Number} skewX\n   * @param {Number} skewY\n   * @param {Number} regX Optional.\n   * @param {Number} regY Optional.\n   * @return {Matrix2D} This matrix. Useful for chaining method calls.\n   **/\n  appendTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) {\n    if (rotation % 360) {\n      var r = rotation * DEG_TO_RAD\n      var cos = Math.cos(r)\n      var sin = Math.sin(r)\n    } else {\n      cos = 1\n      sin = 0\n    }\n\n    if (skewX || skewY) {\n      // TODO: can this be combined into a single append operation?\n      skewX *= DEG_TO_RAD\n      skewY *= DEG_TO_RAD\n      this.append(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y)\n      this.append(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, 0, 0)\n    } else {\n      this.append(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, x, y)\n    }\n\n    if (regX || regY) {\n      // append the registration offset:\n      this.tx -= regX * this.a + regY * this.c\n      this.ty -= regX * this.b + regY * this.d\n    }\n    return this\n  }\n\n  /**\n   * Generates matrix properties from the specified display object transform properties, and prepends them to this matrix.\n   * For example, you could calculate the combined transformation for a child object using:\n   *\n   * \tvar o = myDisplayObject\n   * \tvar mtx = new createjs.Matrix2D()\n   * \tdo  {\n   * \t\t// prepend each parent's transformation in turn:\n   * \t\tmtx.prependTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY)\n   * \t} while (o = o.parent)\n   *\n   * \tNote that the above example would not account for {{#crossLink \"DisplayObject/transformMatrix:property\"}}{{/crossLink}}\n   * \tvalues. See {{#crossLink \"Matrix2D/prependMatrix\"}}{{/crossLink}} for an example that does.\n   * @method prependTransform\n   * @param {Number} x\n   * @param {Number} y\n   * @param {Number} scaleX\n   * @param {Number} scaleY\n   * @param {Number} rotation\n   * @param {Number} skewX\n   * @param {Number} skewY\n   * @param {Number} regX Optional.\n   * @param {Number} regY Optional.\n   * @return {Matrix2D} This matrix. Useful for chaining method calls.\n   **/\n  prependTransform = function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) {\n    if (rotation % 360) {\n        var r = rotation * DEG_TO_RAD\n        var cos = Math.cos(r)\n        var sin = Math.sin(r)\n    } else {\n        cos = 1\n        sin = 0\n    }\n\n    if (regX || regY) {\n        // prepend the registration offset:\n        this.tx -= regX\n        this.ty -= regY\n    }\n    if (skewX || skewY) {\n        // TODO: can this be combined into a single prepend operation?\n        skewX *= DEG_TO_RAD\n        skewY *= DEG_TO_RAD\n        this.prepend(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, 0, 0)\n        this.prepend(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y)\n    } else {\n        this.prepend(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, x, y)\n    }\n    return this\n  }\n}"
  }
]